web-dev-qa-db-fra.com

Express et TypeScript - Les propriétés Error.stack et Error.status n'existent pas

J'essaie de convertir un projet node.js existant de javascript en TypeScript. J'utilise le capteur d'erreur 404 par défaut du modèle Visual Studio Express 4:

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

Cependant, je reçois le message d'erreur suivant: La propriété 'status' n'existe pas sur le type 'Error'.

J'obtiens un message similaire si j'essaie d'invoquer la propriété .stack de l'erreur: La propriété 'stack' n'existe pas sur le type 'Error'.

Est-ce que quelqu'un sait ce qui se passe ici?

Edit: Steve Fenton souligne que je pourrais simplement mettre le statut d'erreur sur l'objet de réponse. Cependant, mon mécanisme de gestion des erreurs utilise un processus en deux étapes:

  1. Créez l'erreur 404 et définissez son état
  2. Remettez-le au gestionnaire générique suivant:

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

Ainsi, le statut d'erreur est d'abord défini sur l'objet Error, puis relu par le gestionnaire d'erreurs pour décider comment gérer l'erreur.

21
Joel

Vous pouvez dire à TypeScript que pour votre cas d'utilisation Error peut avoir un status dessus:

interface Error{
    status?: number;
}

Vous obtenez donc:

interface Error{
    status?: number;
}

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

Cependant, je dois dire que votre code express n'est pas idiomatique, mais TypeScript peut le comprendre, si vous en parlez.

14
basarat

Vous mettez le code d'erreur sur la réponse ...

app.use(function (req, res, next) {
    var err = new Error('Not Found');
    res.status(404)
    next(err);
});
8
Fenton

La meilleure façon, à mon avis, n'est pas de désactiver les vérifications de type en définissant l'erreur sur any, ou en créant un nouveau type Error, car il en existe déjà un dans @types/node.

Au lieu de cela, vous devez étendre ce type d'erreur:

interface ResponseError extends Error {
  status?: number;
}
7
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
  });
});
5
kunl

Il s'agit généralement de savoir comment initialiser des objets paresseusement en TypeScript.

La façon idéale de le faire est:

interface ErrorWithStatus extends Error {
    status: string
}

let foo = new Error() as ErrorWithStatus;
foo.status = '404';

L'utilisation de any, ou d'interfaces avec des champs nullables, vous laisse avec des contrats inférieurs et faibles.

4
dmwong2268

Une autre option dans TypeScript:

const err: { status?: number, message:string } = new Error('Not Found');
err.status = 404;
3
Matthias

Une autre option dans TypeScript:

let err: any;
err = new Error();
err.status = 404;
3
Manu

Si je ne me trompe pas, il est toujours préférable d'obtenir le type qui est réellement attendu. Je n'ai trouvé aucun support dur que j'ai raison, mais j'utilise:

import createError, { HttpError } from 'http-errors';

et pour être complet pour tous les types j'importe aussi les types de paramètres d'utilisation:

import express, { Request, Response, NextFunction } from 'express';

La fonction réelle que j'utilise ressemble alors à ceci:

app.use((err: HttpError, req: Request, res: Response, next: NextFunction) => { ... }

Dans votre cas, si vous souhaitez créer votre propre erreur:

app.use((req: Request, res: Response, next: NextFunction) => {
  next(createError(404));
});

ou plus proche de votre code:

app.use((req: Request, res: Response, next: NextFunction) => {
  let err = new HttpError('Not found');
  err.status = 404;
  next(err);
});
0
Rutger de Graaf

Je suis juste allé pour

var err = new Error('Not Found');
err['status'] = 404;
0
czechboy