2

I'm building an error handling middleware for a node.js with express and TypeScript project. Within it I have a AppError class that extends Error. It looks like this:

class AppError extends Error {
  public readonly internalCode: number | undefined;

  public readonly httpCode: number;

  public readonly message: string;

  constructor(httpCode: number, message: string, internalCode?: number) {
    super();
    this.internalCode = internalCode;
    this.message = message;
    this.httpCode = httpCode;
  }

  public generateReport(): GenericReport {
    return {
      code: this.internalCode,
      message: this.message,
    };
  }
}

I'm currently throwing new AppError() inside a /error route to catch it with the following middleware, errorHandler:

function errorHandler(err: Error, request: Request, response: Response, next: NextFunction,): Response {
  if (err instanceof AppError) {
    const report = err.generateReport();

    return response.status(err.httpCode).json(report);
  }

  return response.status(500).json(err);
}

Inside the middleware I'm trying to find AppError on err [[Prototype]] chain, but the verification always fails in the TypeScript code. However, after transpiling it with Babel and running the JS version with node, err instanceof AppError resolves to true. Why doesn't it in the TS code?

In the example above, Object.getPrototypeOf(err) returns me Error {}, and changing err type to AppError or any doesn't affect the result.

To my understanding, the newly constructed object (after new AppError() runs) should be [[Prototype]]-linked to AppError. And running curl http://localhost:3333/error with the TS server on, I get { "internalCode": 1, "message": "This is an error", "httpCode": 500 }, which means that err is indeed created by AppError().

There's a working example of the problem in this GitHub repository. Any clarification on this topic will be greatly appreciated.

2
  • 1
    What do you mean fails in the typescript code? You don't really run typescript code. It gets converted to Javascript. Have you looked at the output? Might give you a hint. It might be problematic that your output is es5 which is before classes where a thing. Commented Nov 15, 2020 at 3:07
  • @Evert yeah... that was my problem. I had es5 as target in the tsconfig. Thank you very much. I've spent the las hour on this, and it haven't even gone through my mind. Commented Nov 15, 2020 at 3:12

1 Answer 1

1

I took a look at your code. A few comments:

  1. Switching to a later ecmascript output might fix this, as your output does not generate classes right now, because EcmaScript 5 didn't have them yet.
  2. It's a good idea to not use ts-node tools, especially when you're trying to debug something like. It can give funky result, and it's nice to just be able to look at the real javascript being executed.
  3. I took a look at your repo, and I believe that you should probably just use instanceof for what you are trying to do. I think for the purpose of your error middleware, instanceof makes a bit more sense.

If you're interested, I also wrote an error handling middleware that does a similar thing:

https://github.com/curveball/problem/blob/master/src/index.ts

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.