По умолчанию Express возвращает ошибки в виде HTML-страниц. Поскольку я разрабатываю REST api, я хочу, чтобы все мои ошибки были в формате JSON. Как я могу настроить для этого экспресс?
Я ожидаю, что ответ будет выглядеть примерно так
{
"statusCode": 404,
"error": "Not Found"
}
но вместо этого я получаю
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot DELETE /object/</pre>
</body>
</html>
Это мое базовое приложение
export const app = express();
app.use(express.json());
app.get("/objects", listObjects);
app.get("/object/:id", getObject);
app.post("/object", createObject);
app.put("/object/:id", updateObject);
app.delete("/object/:id", deleteObject);
ОБНОВИТЬ: Чтобы уточнить, я хочу обрабатывать как json не ошибки моих обработчиков. Сделать это довольно просто.
То, что мне нужно, - это экспресс, чтобы перестать возвращать ошибки html для незарегистрированных обработчиков, таких как выполнение DELETE на / Assessment или GET на / anUnknownRoute
Я обновил вопрос своим кодом приложения
опубликуйте свою функцию deleteObject. как вы возвращаете объект ответа.
Моя функция deleteObject не имеет значения, потому что я не вызываю ее. Я вызываю DELETE для / object /, к которому не подключен обработчик, вместо / object /: id. Я хочу, чтобы эта ошибка выдавалась в формате json, а не html
app.delete (путь, обратный вызов [, обратный вызов ...]). он ясно показывает, что второй параметр - это функция обратного вызова. затем отправьте формат json из функции обратного вызова deleteObject.
Поскольку я не добавляю идентификатор после косой черты, он не будет вызываться, но на самом деле это совершенно не имеет значения. Прочтите мое обновление в исходном посте, где я объяснюсь более четко





Вы можете просто добавить 'Content-Type: application/json' в заголовки ответов и написать практически все, что захотите, в формате JSON, например.
function(err, req, res, next){
res.setHeader('Content-Type', 'application/json');
res.status(500);
res.send(JSON.stringify(error));
});
Или вы можете использовать вместо него res.json. Пожалуйста, смотрите официальный документ для более подробной информации: https://expressjs.com/en/api.html#res.json
Если вы хотите возвращать ошибки в JSON по умолчанию, то вас может заинтересовать использование механизма экспресс-обработки ошибок по умолчанию: https://expressjs.com/en/guide/error-handling.html
Просто передайте error в обратный вызов next, чтобы перейти прямо к обработчику ошибок (пропуская все остальное в очереди между ними) и добавьте промежуточное ПО обработки ошибок в конец своей очереди промежуточного программного обеспечения. Это должно помочь.
P.S. Из FAQ по express.js:
In Express, 404 responses are not the result of an error, so the error-handler middleware will not capture them. This behavior is because a 404 response simply indicates the absence of additional work to do; in other words, Express has executed all middleware functions and routes, and found that none of them responded. All you need to do is add a middleware function at the very bottom of the stack (below all other functions) to handle a 404 response:
app.use(function (req, res, next) {
res.status(404).send("Sorry can't find that!")
})
Очевидно, вы можете отправить ответ в формате JSON ...
Возможно, я не смог четко объяснить свою проблему. Я знаю, как вернуть ошибки json для любого заданного маршрута. Но когда, например, не обнаружен ни один маршрут, Express выдает собственные ошибки. Это простой html, но я хочу их в json.
@Jakob, вы можете добавить промежуточное ПО, которое будет соответствовать любому из несовпадающих запросов (app.use('/', ...) {}). И тогда это сходится к той же идее, которую я написал выше.
Последняя строка действительно решает мою конкретную проблему, но вводит новую. Вызов OPTIONS к существующей конечной точке больше не работает. Я предполагаю, что может быть и другое нежелательное поведение. Ручной ответ на OPTIONS в моем маршрутизаторе кажется настоящим шагом вниз. Неужели нет способа в express контролировать несовпадающие запросы, не нарушая при этом другое поведение?
@ Якоб Да, я плохо. Это не должно быть так сложно. Ознакомьтесь с FAQ по express.js. Они предоставляют кристально ясное объяснение того, как express.js обрабатывает ошибки 404. expressjs.com/en/starter/faq.html
Спасибо за такую настойчивость, но ваше последнее решение по-прежнему прерывает вызов OPTIONS на допустимые конечные точки. Действительно странно, что такие решения есть в официальных документах
@Jakob Не могли бы вы написать немного кода о том, как вы воспроизводите эту проблему. Это звучит как настоящая ошибка в самой популярной платформе Node.js: D Я также признаю, что неожиданное поведение вызвано каким-то кодом, который вы еще не упомянули.
Это буквально все приложение: gist.github.com/Jakst/5bb4645f154eef8a6b6050d959ad3807 Выполнение вызова OPTIONS на / ping возвращает nope, но если вы удалите app.use(...), он вернет GET,HEAD.
Спасибо, я разместил ваш код в нижней части своего промежуточного программного обеспечения, и он работает: app.use (function (req, res, next) {res.status (404) .send ("Извините, не могу найти это!")})
Я проверил исходный код express.js. Причина, по которой все это заканчивается в формате HTML, заключается в том, что по умолчанию они вызывают finalhandler (см. github.com/expressjs/express/blob/master/lib/application.js) , который производит окончательный вывод только в формате HTML (OT: переменная NODE_ENV обрабатывается Finalhandler, а не Express). Пакет Finalhandler находится здесь: npmjs.com/package/finalhandler.
В Express ответы 404 не являются результатом ошибки, поэтому промежуточное программное обеспечение обработчика ошибок не будет их захватывать - действительно полезно, много thx
Вы добавляете пользовательское промежуточное ПО для обработки ошибок - которое является обычным промежуточным ПО, но с 4 аргументами вместо 3 - в стек промежуточного программного обеспечения. В этом обработчике ошибок вы используете res.status(code).send(jsonResponse) для отправки ошибки json.
Простой быстрый пример, который всегда будет отправлять ошибки JSON статуса 500:
const bodyParser = require('body-parser')
const express = require('express')
const jsonErrorHandler = async (err, req, res, next) => {
res.status(500).send({ error: err });
}
const app = express()
// The other middleware
app.use(bodyParser.json())
// Your handler
app.use(jsonErrorHandler)
ха-ха, я забыл, что ему нужен четвертый аргумент, даже если он не использовался для правильного обнаружения ошибок, я часами боролся с этим глупым глупым перебором, этот ответ решил мою проблему! Благодарность
То же самое, не забывайте аргумент next !! Спасибо @xunux, ты сэкономил мне пару часов своим комментарием
все, что вам нужно сделать для получения ответа JSON об ошибках, - это добавить еще один аргумент в обработчик маршрута, который будет функцией промежуточного программного обеспечения, ответственной за ошибки.
Бывший: вы должны изменить это
app.get('/objects', listObjects);
быть таким:
app.get('/objects', listObjects, (err, req, res, next) => {
res.status(404).send({error: err.message})
});
опубликуйте код обработки вашего маршрутизатора.