Skip to content

Getting error while using " return res.json({ }) " #6022

Closed

Description

@tanmayvaij

using "express": "^4.21.0",
created this middleware for token verification

import { NextFunction, Request, Response } from "express";
import { JwtPayload, verify } from "jsonwebtoken";

declare global {
  namespace Express {
    interface Request {
      user: JwtPayload;
    }
  }
}

export const tokenVerifier = (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const authHeader = req.headers.authorization;

    if (!authHeader)
      return res.json({
        err: "authorization token was not provided",
        isSuccess: false,
      });

    const token = authHeader!.split(" ")[1];

    req.user = verify(
      token,
      process.env.FLEXIBASE_AUTH_SECRET_KEY!
    ) as JwtPayload;

    next();
  } catch (err) {
    return res.json({ isSucess: false, err });
  }
};
D:\Projects\flexibase-auth\node_modules\ts-node\src\index.ts:859
    return new TSError(diagnosticText, diagnosticCodes, diagnostics);
           ^
TSError: ⨯ Unable to compile TypeScript:
src/routers/auth.router.ts:13:38 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '(req: Request, res: Response, next: NextFunction) => Response<any, Record<string, any>> | undefined' is not assignable to parameter of type 'RequestHandlerParams<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
      Type '(req: Request, res: Response, next: NextFunction) => Response<any, Record<string, any>> | undefined' is not assignable to type 'RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
        Type 'Response<any, Record<string, any>> | undefined' is not assignable to type 'void | Promise<void>'.
          Type 'Response<any, Record<string, any>>' is not assignable to type 'void | Promise<void>'.

13 authRouter.route("/verify-user").get(tokenVerifier, verifyUserController);
                                        ~~~~~~~~~~~~~

  node_modules/@types/express-serve-static-core/index.d.ts:203:5
    203     <
            ~
    204         P = ParamsDictionary,
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ...
    212         ...handlers: Array<RequestHandlerParams<P, ResBody, ReqBody, ReqQuery, LocalsObj>>
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    213     ): T;
        ~~~~~~~~~
    The last overload is declared here.

    at createTSError (D:\Projects\flexibase-auth\node_modules\ts-node\src\index.ts:859:12)
    at reportTSError (D:\Projects\flexibase-auth\node_modules\ts-node\src\index.ts:863:19)
    at getOutput (D:\Projects\flexibase-auth\node_modules\ts-node\src\index.ts:1077:36)
    at Object.compile (D:\Projects\flexibase-auth\node_modules\ts-node\src\index.ts:1433:41)
    at Module.m._compile (D:\Projects\flexibase-auth\node_modules\ts-node\src\index.ts:1617:30)
    at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
    at Object.require.extensions.<computed> [as .ts] (D:\Projects\flexibase-auth\node_modules\ts-node\src\index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:1207:32)
    at Function.Module._load (node:internal/modules/cjs/loader:1023:12)
    at Module.require (node:internal/modules/cjs/loader:1235:19) {
  diagnosticCodes: [ 2769 ]

i get this err while starting the server

Activity

  1. tanmayvaij commented on Oct 5, 2024

    @tanmayvaij
    Author

    the problem was in @types/express@5.0.0 , when i used previous version the issue was solved

  2. brettearle commented on Oct 17, 2024

    @brettearle

    EDIT: THIS COMMENT IRRELEVANT

    Looking to lend a hand, what help do you want here? More info on the bug, updated types for 5.0, overload that allows res return?
    Have only read this issue will dig in some tomorrow

  3. brettearle commented on Oct 17, 2024

    @brettearle

    Q1: is it express intention to not call next and return out of a middleware? Doco is only representative of calling next(), to handle errors out of them it's handed to custom error handler
    https://expressjs.com/en/guide/writing-middleware.html

    EDIT: BELOW IRRELEVANT
    Q2: Should app.{verb} take middle ware before final handler, or are these verb fns meant to be single handler end points?

    Note1: I have looked at the types that are throwing in types/express-serve-static-core, they seem to have no changes since v4. This was a quick look.

    Will get to more work over the weekend

  4. brettearle commented on Oct 17, 2024

    @brettearle

    It seems that types for 5 are working as intended because next is the intention of middleware instead of returning directly out of them.
    This is pending answers from library authors as I don't know the intentions for 5

  5. brettearle commented on Oct 18, 2024

    @brettearle

    Related issue #5987

  6. DylasX commented on Oct 25, 2024

    @DylasX

    Hey @tanmayvaij hope you find well, so basically something that you can do with that version of @types/express@5.0.0 is changing a little bit your approach instead of using return res.json you can use the next approach

    export const tokenVerifier =   (
      req: Request,
      res: Response,
      next: NextFunction
    ): void => {
      try {
        const authHeader = req.headers.authorization;
    
        if (!authHeader) 
          return next(JSON.stringify({err: "authorization token was not provided",isSucess: false}));
    
        const token = authHeader!.split(" ")[1];
    
        req.user = verify(
          token,
          process.env.FLEXIBASE_AUTH_SECRET_KEY!
        ) as JwtPayload;
    
        next();
      } catch (err) {
        return next(JSON.stringify({ isSucess: false, err }));
      }
    };
    
  7. DylasX commented on Oct 25, 2024

    @DylasX

    This issue is related to this interface in express-serve-static-core

    export interface RequestHandler<
        P = ParamsDictionary,
        ResBody = any,
        ReqBody = any,
        ReqQuery = ParsedQs,
        LocalsObj extends Record<string, any> = Record<string, any>,
    > {
        // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2)
        (
            req: Request<P, ResBody, ReqBody, ReqQuery, LocalsObj>,
            res: Response<ResBody, LocalsObj>,
            next: NextFunction,
        ): void | Promise<void>;    
    }
    

    adding the Promise<void> in the types/express@5.0.0 is causing this type issue so that's why it's working in previous versions because the interface returned is only void

  8. angezy commented on Nov 11, 2024

    @angezy

    The error you're encountering occurs because the tokenVerifier middleware returns a response in case of an error (res.json(...)). The RequestHandler type from Express expects the middleware to either return void or Promise. Since tokenVerifier is returning Response | undefined, TypeScript throws this error.

    Here’s how to address it:

    Ensure that tokenVerifier always calls next() or returns when it’s done, without returning any response directly.
    Update the error handling to avoid returning the Response. Instead, call next with an error to let Express handle it as an error handler.

    Here's an updated version of tokenVerifier:

    
    import { NextFunction, Request, Response } from "express";
    import { JwtPayload, verify } from "jsonwebtoken";
    
    declare global {
      namespace Express {
        interface Request {
          user?: JwtPayload; // Make user optional to handle cases where it might not be set
        }
      }
    }
    
    export const tokenVerifier = (
      req: Request,
      res: Response,
      next: NextFunction
    ): void => {
      try {
        const authHeader = req.headers.authorization;
    
        if (!authHeader) {
          return res.status(401).json({
            err: "Authorization token was not provided",
            isSuccess: false,
          });
        }
    
        const token = authHeader.split(" ")[1];
    
        req.user = verify(
          token,
          process.env.FLEXIBASE_AUTH_SECRET_KEY!
        ) as JwtPayload;
    
        next();
      } catch (err) {
        // Pass error to the next middleware
        next(err);
      }
    };
    

    Changes Explained

    The return type for tokenVerifier is set to void, making sure it either calls next() or returns a response without breaking Express's expected type.
    If an error occurs, it calls next(err) instead of returning a Response, allowing Express's error-handling middleware to handle it properly.

    If you still encounter issues, make sure that your route handler (verifyUserController) is also typed correctly and doesn’t directly return a response.

  9. locked and limited conversation to collaborators on Nov 12, 2024
  10. converted this issue into a discussion #6172 on Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions