Я разрабатываю промежуточное программное обеспечение для ведения журналов и хочу зарегистрировать тело ответа в 500 ответах. В промежуточном программном обеспечении я устанавливаю обратный вызов для события «finish» по запросу, который генерируется после отправки ответа, но тело ответа в объекте Response отсутствует.
Я предполагаю, что тела нет, потому что гнездо js с экспрессом под капотом отправляет ответ чанками и не сохраняет его в объектах Request или Response.
Но я надеюсь, что есть обходной путь, позволяющий получить тело ответа от объекта Response в промежуточном программном обеспечении, который кто-то нашел. Пример класса промежуточного программного обеспечения, над которым я работаю:
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(request: Request, response: Response, next: NextFunction): void {
const { ip, method, originalUrl } = request;
const userAgent = request.get("user-agent") || "";
response.on("finish", () => {
const { statusCode } = response;
const contentLength = response.get("content-length");
const basicRequestMetaInfo = {
method,
originalUrl,
statusCode,
... // other data
};
if (this.isErroneousStatusCode(statusCode)) {
const additionalRequestMetaInfo = {
body: response.body, // The place i want to reach Response body
};
this.winstonLoggerErrorLevel.error({
...basicRequestMetaInfo,
...additionalRequestMetaInfo,
});
return;
}
this.winstonLoggerInfoLevel.info(basicRequestMetaInfo);
});
next();
}
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В этой статье объясняется, как преобразовать фрагменты буфера в читаемый ответ.
Это код из статьи, который вам понадобится, с некоторыми машинописными текстами, которые вы можете изменить по мере необходимости:
const getResponseLog = (res: Response) => {
const rawResponse = res.write;
const rawResponseEnd = res.end;
const chunkBuffers = [];
res.write = (...chunks) => {
const resArgs = [];
for (let i = 0; i < chunks.length; i++) {
resArgs[i] = chunks[i];
if (!resArgs[i]) {
res.once('drain', res.write);
i--;
}
}
if (resArgs[0]) {
chunkBuffers.push(Buffer.from(resArgs[0]));
}
return rawResponse.apply(res, resArgs);
};
console.info(`Done writing, beginning res.end`);
res.end = (...chunk) => {
const resArgs = [];
for (let i = 0; i < chunk.length; i++) {
resArgs[i] = chunk[i];
}
if (resArgs[0]) {
chunkBuffers.push(Buffer.from(resArgs[0]));
}
const body = Buffer.concat(chunkBuffers).toString('utf8');
res.setHeader('origin', 'restjs-req-res-logging-repo');
const responseLog = {
response: {
statusCode: res.statusCode,
body: JSON.parse(body) || body || {},
// Returns a shallow copy of the current outgoing headers
headers: res.getHeaders(),
},
};
console.info('res: ', responseLog);
rawResponseEnd.apply(res, resArgs);
return responseLog as unknown as Response;
};
};