ExpressJS отправляет стек в рабочем режиме

#node.js #typescript #express #environment-variables

Вопрос:

Я пытаюсь смоделировать производство перед выходом в эфир, и у меня есть следующая настройка

пакет.json

 "start": "cross-env NODE_ENV=production node dist/index.js",
 

индекс.ts

 console.log(process.env.NODE_ENV) // prints "production"
router.use(handleError);
 

обработчик ошибок.ts

 import { serializeError } from 'serialize-error';

export function handleError(
  err: ResponseError,
  _req: Request,
  resp: Response,
  _next: NextFunction
): void {
  if (err) {
    resp.status(err.statusCode || 500).json(serializeError(err));
  }
}
 

При такой настройке, когда возникает запрос на ошибку, я получаю стек в ответе, который мне не нужен.

Если я добавлю в функцию обработчика ошибок

   if (err) {
     if (process.env.NODE_ENV === 'production') { 
          delete err.stack;
          resp.status(err.statusCode || 500).json(serializeError(err));
     }
  }
 

тогда я не получу стопку. Но разве Express не должен автоматически удалять стек в процессе работы?

Комментарии:

1. У Express здесь нет шансов, потому что вы сами сериализуете объект ошибки и отправляете его. Итак, вы взяли на себя эту работу в «Экспрессе». Стек по-прежнему будет находиться в самом объекте ошибки. Это исходит из источника ошибки.

2. @jfriend00 хорошо, большое спасибо за этот комментарий. В этом был смысл. Я действительно помню, что мне был нужен этот сериализатор.. Есть ли что-нибудь в функциях Express по умолчанию, помимо этого стека, из-за чего моя ошибка сериализации не позволяет мне извлечь выгоду? Я думаю, что если это только для стека, то я могу использовать обходной путь, который я предложил в ОП.

Ответ №1:

У Express здесь нет шансов, потому что вы сами сериализуете объект ошибки и отправляете его. Итак, вы взяли на себя эту работу в «Экспрессе». Стек по-прежнему будет находиться в самом объекте ошибки. Это исходит из источника ошибки.

Если вы хотите отправить стек ошибок в непроизводственном режиме, я бы предложил изменить ваше предложение следующим образом:

 if (err) {
     if (process.env.NODE_ENV === 'production') { 
          delete err.stack;
     }
     resp.status(err.statusCode || 500).json(serializeError(err));
}
 

Хотя я никогда не отправляю трассировку стека как часть ответа. Вместо этого я всегда регистрирую ошибку локально:

 if (err) {
     console.log(err);
     delete err.stack;
     resp.status(err.statusCode || 500).json(serializeError(err));
}
 

Есть ли что-нибудь в функциях Express по умолчанию, помимо этого стека, из-за чего моя ошибка сериализации не позволяет мне извлечь выгоду?

Стоит прочитать страницу Express doc об обработке ошибок. Их обработчик по умолчанию пытается вести себя по-другому, если заголовки уже были отправлены (например, вы столкнулись с ошибкой при отправке ответа), поскольку в этот момент ваши возможности намного более ограничены.

Они также заставляют все err.statusCode , что не является 4xx или 5xx, равняться 500, так как они хотят убедиться, что об этом сообщается как о коде состояния ошибки. Вы позволяете проходить всему, что находится в объекте ошибки.