Skip to content

Commit

Permalink
feat(server-dev): Log errors in dev server.
Browse files Browse the repository at this point in the history
  • Loading branch information
SamTolmay committed Jul 19, 2023
1 parent ed36f2f commit cacdc12
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 70 deletions.
43 changes: 20 additions & 23 deletions packages/server-dev/lib/server/apiWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,41 +24,38 @@ import createLogger from './log/createLogger.js';
import fileCache from './fileCache.js';
import getServerSession from './auth/getServerSession.js';
import logRequest from './log/logRequest.js';
import logError from './log/logError.js';
import operators from '../../build/plugins/operators/server.js';
import getAuthOptions from './auth/getAuthOptions.js';

function apiWrapper(handler) {
return async function wrappedHandler(req, res) {
let logger = console;
try {
const rid = crypto.randomUUID();
logger = createLogger({ rid });
const authOptions = getAuthOptions({ logger });
const session = await getServerSession({ authOptions, req, res });
const context = {
// Important to give absolute path so Next can trace build files
const context = createApiContext({
authOptions,
buildDirectory: path.join(process.cwd(), 'build'),
config,
connections,
fileCache,
headers: req.headers,
logger,
operators,
secrets: getSecretsFromEnv(),
session,
req,
});
rid: crypto.randomUUID(),
buildDirectory: path.join(process.cwd(), 'build'),
config,
connections,
fileCache,
headers: req?.headers,
logger: console,
operators,
req,
res,
};
try {
context.logger = createLogger({ rid: context.rid });
context.authOptions = getAuthOptions(context);
context.session = await getServerSession(context);
context.secrets = getSecretsFromEnv();
createApiContext(context);
logRequest({ context });
// Await here so that if handler throws it is caught.
const response = await handler({ context, req, res });
// TODO: Log response time?
return response;
} catch (error) {
// TODO: Improve (logError function)
// TODO: Log cause
logger.error(error);
// TODO: What we do here?
logError({ error, context });
res.status(500).json({ name: error.name, message: error.message });
}
};
Expand Down
40 changes: 40 additions & 0 deletions packages/server-dev/lib/server/log/logError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Copyright 2020-2023 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

function logError({ context, error }) {
try {
const { user = {} } = context;

context.logger.error({
err: error,
user: {
id: user.id,
roles: user.roles,
sub: user.sub,
session_id: user.session_id,
},
url: context.req.url,
method: context.req.method,
resolvedUrl: context.nextContext?.resolvedUrl,
});
} catch (e) {
console.error(error);
console.error('An error occurred while logging the error.');
console.error(e);
}
}

export default logError;
47 changes: 2 additions & 45 deletions packages/server-dev/lib/server/log/logRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,62 +15,19 @@
*/

// TODO: Better name needed here maybe?
function logRequest({ context, metadata = {} }) {
function logRequest({ context }) {
const { user = {} } = context;
context.logger.debug({
// TODO:
// app_name
// app_version
// lowdefy_version
// build_hash
// config_hash
user: {
id: user.id,
roles: user.roles,
sub: user.sub,
session_id: user.session_id, // TODO: Implement session id
session_id: user.session_id,
},
url: context.req.url,
method: context.req.method,
resolvedUrl: context.nextContext?.resolvedUrl,
hostname: context.req.hostname,
...metadata,
});
// TODO:
// Next local? nextContext.locale, nextContext.locales, nextContext.defaultLocale
// console.log('params', nextContext.params);
}

export default logRequest;

/*
User ID
Session ID
Event Type/Action
Timestamp
Source IP Address
User Agent
Resource ID/Identifier
Outcome/Status
Reason
Details/Additional Information
Targeted System
Page URL
Referrer URL
IP Address
Response Time
Error Messages
Device Information
Input Data
Behavioral Metrics
Error Level/Severity
Error Message
Error Code
HTTP Method
Stack Trace
Payload/Body
Application Version
Environment Information
*/
2 changes: 0 additions & 2 deletions packages/server/lib/server/apiWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ function apiWrapper(handler) {
context.logger = createLogger({ rid: context.rid });
context.authOptions = getAuthOptions(context);
context.session = await getServerSession(context);
// Important to give absolute path so Next can trace build files
context.secrets = getSecretsFromEnv();
createApiContext(context);
logRequest({ context });
Expand All @@ -56,7 +55,6 @@ function apiWrapper(handler) {
return response;
} catch (error) {
logError({ error, context });

res.status(500).json({ name: error.name, message: error.message });
}
};
Expand Down

0 comments on commit cacdc12

Please sign in to comment.