2013-04-04 14 views
29

Chcę złapać błąd z middleware bodyParser(), gdy wysyłam obiekt json i jest on nieprawidłowy, ponieważ chcę wysłać niestandardową odpowiedź zamiast ogólnego błędu 400.Catch express bodyParser error

To jest to, co mam i to działa:

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

Ale wydaje mi się bardzo brzydki podejście bo mam porównanie komunikat o błędzie, które mogą ulec zmianie w przyszłych wersjach ekspresowych. Czy istnieje jakikolwiek inny sposób na złapanie błędów bodyParser()?

EDIT:

Jest to błąd, gdy organizm zapytanie ma nieprawidłową JSON:

{ 
    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 
} 

Dość drukowane stosu:

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) 

Odpowiedz

5

Ok, uznał go:

bodyParser() jest funkcją wygoda dla json(), urlencoded() i wielowarstwowy(). Muszę tylko wywołać json(), złapać błąd i wywołać metodę urlencoded() i multipart().

bodyParser source

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()); 
+4

To nie jest rozwiązanie. Nie bierzesz pod uwagę, że zanim ten kod może być innym oprogramowaniem pośredniczącym.Jeśli złapiesz w taki sposób wyjątek, może to prowadzić do nieprzewidywalnego stanu. Przynajmniej lepiej napisać: 'app.use (function (error, req, res, next) {/ * Shutdown node * /}; app.use (bodyParser.json()); app.use (function (error, req, res, next) {/ * if err.status == 4 ** następnie obsłużyć błąd json => res.status (400) .send(), else shutdown node * /}); ' – Dao

+4

NIEBEZPIECZEŃSTWO NIEBEZPIECZEŃSTWO, to zaczepienie Jakikolwiek błąd w powyższym oprogramowaniu pośrednim, jak @Dao powiedział Unsafe – light24bulbs

17

Myślę, że najlepiej jest, aby sprawdzić, SyntaxError:

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

To nie działa, ponieważ nie jest to SyntaxError. Zobacz aktualizację pytania. –

+0

@GabrielLlamas Z najnowszą wersją Express (4.6.1) moduł 'bodyParser' nie jest już wbudowany, został przeniesiony do własnego [modułu] (https://github.com/expressjs/body-parser) i faktycznie rzuca 'SyntaxError' dla źle sformułowanego JSON. – James

+2

Jeśli treść żądania jest zbyt duża, wystąpi błąd zamiast błędu SyntaxError. Na przykład: '{[Błąd: Żądanie jednostka zbyt duża] typu: 'entity.too.large', wiadomość: 'Żądanie podmiot zbyt duże', statusCode: 413, cywilny: 413, spodziewanych: 322350, length: 322350, limit: 102400} ' –

1

znalazłem sprawdzanie SyntaxError za mało, dlatego robię:

if (err instanceof SyntaxError && 
    err.status >= 400 && err.status < 500 && 
    err.message.indexOf('JSON')) { 
    // process filtered exception here 
} 
1
(bodyParser, req, res) => new Promise((resolve, reject) => { 
    try { 
     bodyParser(req, res, err => { 
      if (err instanceof Error) { 
       reject(err); 
      } else { 
       resolve(); 
      } 
     }); 
    } catch (e) { 
     reject(e); 
    } 
}) 

kuloodporne. Przyszły na świat. WTFPL-Licensed. A także przydatne w/async/czekają.

+0

Jak mam podłączyć tę funkcję do mojej aplikacji jako middleware po? Gdzie mogę umieścić kod, który faktycznie reaguje na błąd? Co to robi? – PoolOfPeas

0

Z odpowiedzią @alexander ale na przykładzie ussage

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(); 
} 
Powiązane problemy