Skip to content

Commit

Permalink
added the isExpectedError parameter to requestLogger.RESPONSE()
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaWise committed Nov 6, 2023
1 parent 955dd50 commit 3cb9a79
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/writers.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ The following methods each write data to the log file. Each method is used for a

- `requestLogger.REQUEST(req)`: This SHOULD be logged when the associated HTTP request is first received by the server. Only the request's "head" needs to be received; the request body may still be pending.
- `requestLogger.REQUEST_META(data)`: This can be logged to associate arbitrary application-specific metadata to the request.
- `requestLogger.RESPONSE(statusCode[, error])`: This SHOULD be logged when a response is sent for the associated HTTP request. Only the response's "head" needs to be sent; the response body may still be pending. Passing an `error` indicates that an unexpected error occurred while trying to handle the request.
- `requestLogger.RESPONSE(statusCode[, error[, isExpectedError]])`: This SHOULD be logged when a response is sent for the associated HTTP request. Only the response's "head" needs to be sent; the response body may still be pending. Passing an `error` indicates that an unexpected error occurred while trying to handle the request. Setting `isExpectedError` to `true` causes the error's stack trace to be omitted and the log level to be INFO instead of ERROR.
- `requestLogger.RESPONSE_FINISHED([error])`: This SHOULD be logged when the response body is done being sent (even if the response body was empty). Passing an `error` indicates that an unexpected error occurred while trying to send the response body, after the response's "head" was already sent.
- `requestLogger.critical(data)`: This writes a CRITICAL-level log.
- `requestLogger.error(data)`: This writes an ERROR-level log.
Expand Down
9 changes: 7 additions & 2 deletions src/nodejs/request-logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,23 @@ module.exports = class RequestLogger {
return this;
}

RESPONSE(statusCode, err) {
RESPONSE(statusCode, err, isExpectedError = false) {
if (!Number.isInteger(statusCode)) {
throw new TypeError('Expected statusCode to be an integer');
}
if (typeof isExpectedError !== 'boolean') {
throw new TypeError('Expected third argument to be a boolean, if provided');
}
const parent = this._parent;
if (parent._fd >= 0) {
const writer = createWriter(RESPONSE, parent, this._requestIdBuffer);

if (err == null) {
writer.string('');
writer.uint8(0);
} else {
writer.json(ExceptionUtil.encode(err, this._debugLogs));
writer.json(ExceptionUtil.encode(err, this._debugLogs, isExpectedError));
writer.uint8(isExpectedError ? 1 : 0);
this._debugLogs = null;
}

Expand Down
4 changes: 2 additions & 2 deletions src/shared/exception-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const ARBITRARY_VALUE = 0;
const ERROR_LIKE = 1;

// Serializes an exception for logging purposes.
exports.encode = (err, debugLogs) => {
exports.encode = (err, debugLogs, isExpectedError = false) => {
let type = ARBITRARY_VALUE;
let value = '';
const properties = {};
Expand All @@ -14,7 +14,7 @@ exports.encode = (err, debugLogs) => {
assignProperties(properties, err);

const { stack, message, name } = err;
if (typeof stack === 'string') {
if (!isExpectedError && typeof stack === 'string') {
value = stack;
type = ERROR_LIKE;
} else if (typeof message === 'string') {
Expand Down
7 changes: 5 additions & 2 deletions src/shared/log-entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,20 @@ module.exports = class LogEntry {
this.requestId = reader.bytes(16);
this.data = reader.string();
break;
case RESPONSE:
case RESPONSE: {
this.level = LogLevel.INFO;
this.type = LogType.RESPONSE;
this.workerId = reader.dynamicInteger();
this.requestId = reader.bytes(16);
this.error = reader.string() || null;
const flagByte = reader.uint8();
this.statusCode = reader.dynamicInteger();
if (this.error) {
const isExpectedError = (flagByte & 1) === 1;
if (!isExpectedError && this.error) {
this.level = LogLevel.ERROR;
}
break;
}
case RESPONSE_FINISHED:
this.level = LogLevel.INFO;
this.type = LogType.RESPONSE_FINISHED;
Expand Down
11 changes: 11 additions & 0 deletions test/23.request-logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ describe('RequestLogger', function () {
requestLogger._requestIdBuffer = REQUEST_ID;
expect(requestLogger.RESPONSE(200)).to.equal(requestLogger);
expect(requestLogger.RESPONSE(400, err)).to.equal(requestLogger);
expect(requestLogger.RESPONSE(400, err, true)).to.equal(requestLogger);
expect(fs.readFileSync(util.current())).to.deep.equal(new Uint8Array());
await new Promise(r => setTimeout(r, 60));
const reader = new Reader(fs.readFileSync(util.current()));
Expand All @@ -125,6 +126,16 @@ describe('RequestLogger', function () {
error: JSON.stringify(ExceptionUtil.encode(err)),
statusCode: 400,
});
expect(new LogEntry(reader)).to.deep.equal({
timestamp: TIMESTAMP,
nonce: 2,
level: LogLevel.INFO,
type: LogType.RESPONSE,
workerId: 23,
requestId: BufferUtil.normalize(uuidParse(requestLogger.requestId)),
error: JSON.stringify(ExceptionUtil.encode(err, null, true)),
statusCode: 400,
});
});

specify('RESPONSE_FINISHED() logs an event', async function () {
Expand Down

0 comments on commit 3cb9a79

Please sign in to comment.