Skip to content

Commit aa18e25

Browse files
committed
fix: pino only does error(err,str) or info/warn(str)
1 parent b7fdefc commit aa18e25

File tree

1 file changed

+42
-29
lines changed

1 file changed

+42
-29
lines changed

src/server.js

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,19 @@ server.register(compression, {
4747
server.setErrorHandler((error, request, reply) => {
4848
const alreadySent = reply.sent || reply.raw.headersSent || reply.raw.writableEnded;
4949
const errorCode = error.statusCode || 500;
50-
const errorLog = {
51-
reqId: request.id,
52-
correlationId: request.correlationId,
53-
url: request.url,
54-
method: request.method,
55-
statusCode: errorCode,
56-
error: error.message,
57-
stack: error.stack
58-
};
59-
request.log.error(errorLog);
50+
if(error.stack){
51+
const wrappedError = new Error(error.message);
52+
wrappedError.stack = error.stack;
53+
// important! the first parameter of log.error is the error object with an optional second parameter
54+
// for the message.
55+
request.log.error(wrappedError, `Request error: ${error.message}`);
56+
} else {
57+
// if the error is not an instance of Error, we should log it as a string. if first parameter is a string,
58+
// then args from the second parameter are ignored. so always only log:
59+
// one string parameter or (err,string) for request.log.error
60+
// for request.log.info, pino only supports a single string parameter. this is important for logs to work.
61+
request.log.error(`Request error: ${error.message}`);
62+
}
6063
if(alreadySent){
6164
// the api already set the appropriate error message. we shouldnt do anything now.
6265
return;
@@ -85,11 +88,20 @@ server.addHook('onRequest', (request, reply, done) => {
8588

8689
request.startTime = Date.now();
8790
if (request.headers['content-length']) {
91+
// for request.log.info, pino only supports a single string parameter or a serializable json
92+
// with a `message` attribute like below. this is important for logs to work. you can put in url and other
93+
// ewll known fields we support in our logging dashboard. you need not do this, only a string is needed and
94+
// in dashboard the request id is injected with the log line. use object instead of string only for
95+
// additional attributes like correlation id, url, size etc. these needs not be with every request as you
96+
// can search all these with the request id in the dashboard to get context, so plain strings are
97+
// recommended for logging info in most cases.
8898
request.log.info({
99+
message: 'Request size',
89100
reqId: request.id,
101+
url: request.url,
90102
correlationId: request.correlationId,
91103
size: `${request.headers['content-length']} bytes`
92-
}, 'Request size');
104+
});
93105
}
94106
done();
95107
});
@@ -109,31 +121,27 @@ server.addHook('onRequest', (request, reply, done) => {
109121
});
110122
if (!routeExists) {
111123
request.log.error({
124+
message: 'Route not found',
112125
reqId: request.id,
113126
correlationId: request.correlationId,
114127
url: sanitizedUrl,
115128
method: request.method,
116129
ip: request.ips
117-
}, "Route not found");
130+
});
118131
reply.code(HTTP_STATUS_CODES.NOT_FOUND);
119132
return reply.send({error: 'Not Found'});
120133
} else if (!isAuthenticated(request)) {
121134
request.log.warn({
135+
message: 'Unauthorized access attempt',
122136
reqId: request.id,
123137
correlationId: request.correlationId,
124138
url: sanitizedUrl,
125139
method: request.method,
126140
ip: request.ips
127-
}, "Unauthorized access attempt");
141+
});
128142
reply.code(HTTP_STATUS_CODES.UNAUTHORIZED);
129143
return reply.send({error: 'Unauthorized'});
130144
}
131-
request.log.info({
132-
reqId: request.id,
133-
correlationId: request.correlationId,
134-
url: sanitizedUrl,
135-
method: request.method
136-
}, "Request authenticated");
137145
done();
138146
});
139147

@@ -153,13 +161,14 @@ server.addHook('onRequest', (request, reply, done) => {
153161
server.addHook('onResponse', (request, reply, done) => {
154162
const duration = Date.now() - request.startTime;
155163
request.log.info({
164+
message: 'Request completed',
156165
reqId: request.id,
157166
correlationId: request.correlationId,
158167
url: request.url,
159168
method: request.method,
160169
statusCode: reply.statusCode,
161170
duration: `${duration}ms`
162-
}, 'Request completed');
171+
});
163172
done();
164173
});
165174

@@ -264,9 +273,9 @@ export async function startServer() {
264273
port: configs.port,
265274
host: configs.allowPublicAccess ? '0.0.0.0' : 'localhost'
266275
});
267-
server.log.info({message: `Server started on port ${configs.port}`});
276+
server.log.info(`Server started on port ${configs.port}`);
268277
} catch (err) {
269-
server.log.error({message: 'Error starting server', error: err});
278+
server.log.error(err, 'Error starting server');
270279
process.exit(1);
271280
}
272281
}
@@ -278,41 +287,45 @@ export async function close() {
278287
server.log.info({message: 'Shutting down server...'});
279288
try {
280289
const shutdownTimeout = setTimeout(() => {
281-
server.log.error({message: 'Forced shutdown after timeout'});
290+
server.log.error('Forced shutdown after timeout');
282291
process.exit(1);
283292
}, CLEANUP_GRACE_TIME_5SEC);
284293

285294
await server.close();
286295
clearTimeout(shutdownTimeout);
287-
server.log.info({message: 'Server shut down successfully'});
296+
server.log.info('Server shut down successfully');
288297
} catch (err) {
289-
server.log.error({message: 'Error during shutdown', error: err});
298+
server.log.error(err, 'Error during shutdown');
290299
process.exit(1);
291300
}
292301
}
293302

294303
// Handle process termination
295304
process.on('SIGTERM', async () => {
296-
server.log.info({message: 'SIGTERM received'});
305+
server.log.info('SIGTERM received');
297306
await close();
298307
process.exit(0);
299308
});
300309

301310
process.on('SIGINT', async () => {
302-
server.log.info({message: 'SIGINT received'});
311+
server.log.info('SIGINT received');
303312
await close();
304313
process.exit(0);
305314
});
306315

307316
// Handle uncaught exceptions
308317
process.on('uncaughtException', (err) => {
309-
server.log.error({message: 'Uncaught Exception', error: err});
318+
server.log.error(err, 'Uncaught Exception');
310319
close().then(() => process.exit(1));
311320
});
312321

313322
// Handle unhandled promise rejections
314323
process.on('unhandledRejection', (reason, promise) => {
315324
// non error rejections do not have a stack trace and hence cannot be located.
316-
server.log.error({message: 'Unhandled Rejection at promise', error: reason instanceof Error ? reason : { reason }, promise});
325+
if(reason instanceof Error){
326+
server.log.error(reason, 'Unhandled Rejection at promise');
327+
} else {
328+
server.log.error('Unhandled Rejection at promise. reason:' + reason);
329+
}
317330
close().then(() => process.exit(1));
318331
});

0 commit comments

Comments
 (0)