web-dev-qa-db-fra.com

Erreur Catch Express bodyParser

Je souhaite intercepter l'erreur du middleware bodyParser () lorsque j'envoie un objet json. Il est invalide car je souhaite envoyer une réponse personnalisée au lieu d'une erreur 400 générique.

C'est ce que j'ai et ça marche:

app.use (express.bodyParser ());
app.use (function (error, req, res, next){
    //Catch bodyParser error
    if (error.message === "invalid json"){
        sendError (res, myCustomErrorMessage);
    }else{
        next ();
    }
});

Mais cela me semble une approche très laide, car je compare le message d’erreur qui pourrait changer dans les futures versions Express. Il existe un autre moyen d'attraper les erreurs bodyParser ()?

MODIFIER:

C'est l'erreur quand le corps de la requête a un json invalide:

{
  stack: 'Error: invalid json\n    at Object.exports.error (<path>/node_modules/express/node_modules/connect/lib/utils.js:55:13)\n    at IncomingMessage.<anonymous> (<path>/node_modules/express/node_modules/connect/lib/middleware/json.js:74:71)\n    at IncomingMessage.EventEmitter.emit (events.js:92:17)\n    at _stream_readable.js:872:14\n    at process._tickDomainCallback (node.js:459:13)',
  arguments: undefined,
  type: undefined,
  message: 'invalid json',
  status: 400
}

Jolie pile imprimée:

Error: invalid json
    at Object.exports.error (<path>/node_modules/express/node_modules/connect/lib/utils.js:55:13)
    at IncomingMessage.<anonymous> (<path>/node_modules/express/node_modules/connect/lib/middleware/json.js:74:71)
    at IncomingMessage.EventEmitter.emit (events.js:92:17)
    at _stream_readable.js:872:14
    at process._tickDomainCallback (node.js:459:13)
35
Gabriel Llamas

Ok, je l'ai trouvé:

bodyParser () est une fonction pratique pour json (), urlencoded () et multipart (). J'ai juste besoin d'appeler json (), de détecter l'erreur et d'appeler urlencoded () et multipart ().

source bodyParser

app.use (express.json ());
app.use (function (error, req, res, next){
    //Catch json error
    sendError (res, myCustomErrorMessage);
});

app.use (express.urlencoded ());
app.use (express.multipart ());
3
Gabriel Llamas

Je pense que votre meilleur pari est de vérifier SyntaxError:

app.use(function (error, req, res, next) {
  if (error instanceof SyntaxError) {
    sendError(res, myCustomErrorMessage);
  } else {
    next();
  }
});
19
robertklep

D'après la réponse de @alexander mais avec un exemple d'utilisation

app.use((req, res, next) => {
    bodyParser.json({
        verify: addRawBody,
    })(req, res, (err) => {
        if (err) {
            console.log(err);
            res.sendStatus(400);
            return;
        }
        next();
    });
});

function addRawBody(req, res, buf, encoding) {
    req.rawBody = buf.toString();
}
10
Daniel Pérez
(bodyParser, req, res) => new Promise((resolve, reject) => {
    try {
        bodyParser(req, res, err => {
            if (err instanceof Error) {
                reject(err);
            } else {
                resolve();
            }
        });
    } catch (e) {
        reject(e);
    }
})

Blindé. Conscient de l'avenir. WTFPL-Licensé. Et aussi utile w/async/wait.

J'ai trouvé que vérifier pour SyntaxError n'était pas suffisant, donc je fais:

if (err instanceof SyntaxError &&
  err.status >= 400 && err.status < 500 &&
  err.message.indexOf('JSON')) {
    // process filtered exception here
}
1
dudko