Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express and Typescript - Error.stack and Error.status properties do not exist

I'm trying to convert an existing node.js project from javascript to typescript. I've been using the default 404 error catcher from the Visual Studio Express 4 template:

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

However, I'm getting the following error message: Property 'status' does not exist on type 'Error'.

I get a similar message if I try and invoke the Error's .stack property: Property 'stack' does not exist on type 'Error'.

Does anyone know what's going on here?

Edit: Steve Fenton points out that I could just put the error status on the response object. However, my error handling mechanism uses a two-step process:

  1. Create the 404 error and set its status
  2. Hand it on to the following generic handler:

    app.use(function (err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: {}
        });
    });
    

So the error status is first set on the Error object, then read back by the error handler to decide how to handle the error.

like image 401
Joel Avatar asked Mar 01 '15 11:03

Joel


4 Answers

Extend global Error

You can tell TypeScript that for your use case Error might have a status on it:

interface Error {
    status?: number;
}

So you get:

interface Error {
    status?: number;
}

var err = new Error('Not Found');
err.status = 404;

Alternative

Put the status on the res and send the err. For Example:

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    res.status(404); // using response here
    next(err);
});
like image 190
basarat Avatar answered Oct 18 '22 17:10

basarat


The best way in my opinion, is not to disable type checks by setting the error to any, or creating a new Error type, since one already exists in @types/node.

Instead, you should extend that error type:

interface ResponseError extends Error {
  status?: number;
}
like image 35
Reinstate Monica Avatar answered Oct 18 '22 19:10

Reinstate Monica


import * as express from 'express';
interface Error {
  status?: number;
  message?: string;
}

app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: err
  });
});
like image 12
kunl Avatar answered Oct 18 '22 18:10

kunl


You put the error code on the response...

app.use(function (req, res, next) {
    var err = new Error('Not Found');
    res.status(404)
    next(err);
});
like image 8
Fenton Avatar answered Oct 18 '22 17:10

Fenton