2013-04-04 5 views
29

Я хочу поймать ошибку из промежуточного программного обеспечения bodyParser() при отправке json-объекта, и это неверно, потому что я хочу отправить настраиваемый ответ вместо общей ошибки 400.Catch express bodyParser error

Это то, что у меня есть, и она работает:

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

Но это мне кажется очень некрасиво подход, потому что я сравниваю сообщение об ошибке, которое может измениться в будущих версиях экспресс. Есть ли другой способ уловить ошибки bodyParser()?

EDIT:

Это ошибка, когда тело запроса имеет недопустимое 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 
} 

Довольно печататься стек:

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) 

ответ

5

ОК, нашел его:

bodyParser() - функция удобства для json(), urlencoded() и multipart(). Мне просто нужно вызвать json(), поймать ошибку и вызвать urlencoded() и 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

Это не решение. Вы не принимаете во внимание, что до того, как этот код станет другим промежуточным программным обеспечением.Если вы поймете таким образом какое-то исключение, это может привести к непредсказуемому состоянию. По крайней мере, лучше написать: 'app.use (функция (ошибка, req, res, next) {/ * Shutdown node * /}; app.use (bodyParser.json()); app.use (функция (ошибка, req, res, next) {/ * if err.status == 4 ** затем обрабатывать json error => res.status (400) .send(), else shutdown node * /}); ' – Dao

+4

ОПАСНО ОПАСНОСТЬ, это ловит любая ошибка в предыдущем промежуточном программном обеспечении, как сказал @Dao Unsafe – light24bulbs

17

Я думаю, вам лучше всего, чтобы проверить SyntaxError:

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

Это не работает, потому что это не SyntaxError. См. Обновление вопроса. –

+0

@GabrielLlamas С новейшей версией Express (4.6.1) модуль 'bodyParser' больше не встроен, он был перемещен в собственный [модуль] (https://github.com/expressjs/body-parser), и это действительно вызывает «SyntaxError» для искаженного JSON. – James

+2

Если тело запроса слишком велико, однако вы получите сообщение об ошибке вместо SyntaxError. Например: '{[Ошибка: объект запроса слишком большой] типа: 'entity.too.large', сообщение: 'объект запроса слишком большой', StatusCode: 413, статус: 413, ожидается: 322350, длина: 322350, limit: 102400} ' –

1

Я нашел проверки SyntaxError быть недостаточно, поэтому я делаю:

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); 
    } 
}) 

пуленепробиваемые. Перспективная известно. WTFPL-Лицензированный. А также полезно w/async/await.

+0

Как включить эту функцию в мое приложение в качестве промежуточного программного обеспечения после этого? Где я могу поместить код, который действительно отвечает на ошибку? Что это такое? – PoolOfPeas

0

Из ответа @alexander но с примером 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(); 
} 
Смежные вопросы