Skip to content

Commit

Permalink
fix: logging setup and error card error display (#349)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas-jonas authored Aug 21, 2024
1 parent ddf94f3 commit 93d540f
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 14 deletions.
3 changes: 2 additions & 1 deletion nodemon.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"DANGEROUSLY_DISABLE_SECURE_CSRF_COOKIES": "true",
"ORY_SDK_URL": "http://localhost:4433",
"KRATOS_PUBLIC_URL": "http://localhost:4433",
"KRATOS_ADMIN_URL": "http://localhost:4434"
"KRATOS_ADMIN_URL": "http://localhost:4434",
"NODE_ENV": "development"
}
}
42 changes: 40 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"dependencies": {
"@ory/client": "1.14.3",
"@ory/elements-markup": "0.3.0-rc.1",
"@redtea/format-axios-error": "2.1.1",
"accept-language-parser": "1.5.0",
"axios": "1.7.4",
"body-parser": "1.20.2",
Expand Down
10 changes: 5 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ app.use(baseUrl, router)
const port = Number(process.env.PORT) || 3000

let listener = (proto: "http" | "https") => () => {
console.log(`Listening on ${proto}://0.0.0.0:${port}`)
logger.info(`Listening on ${proto}://0.0.0.0:${port}`)
}

// When using the Ory Admin API Token, we assume that this application is also
Expand All @@ -128,16 +128,16 @@ if (
String(process.env.CSRF_COOKIE_NAME || "").length === 0 ||
String(process.env.CSRF_COOKIE_SECRET || "").length < 8
) {
console.error(
logger.error(
"Cannot start the server without the required environment variables!",
)
console.error(
logger.error(
"COOKIE_SECRET must be set and be at least 8 alphanumerical character `export COOKIE_SECRET=...`",
)
console.error(
logger.error(
"CSRF_COOKIE_NAME must be set! Prefix the name to scope it to your domain `__HOST-` `export CSRF_COOKIE_NAME=...`",
)
console.error(
logger.error(
"CSRF_COOKIE_SECRET must be set and be at least 8 alphanumerical character `export CSRF_COOKIE_SECRET=...`",
)
} else {
Expand Down
30 changes: 28 additions & 2 deletions src/pkg/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,35 @@
import expressWinston from "express-winston"
import winston from "winston"

let format: winston.Logform.Format = winston.format.json()
if (process.env.NODE_ENV === "development") {
format = winston.format.combine(
winston.format.simple(),
winston.format.colorize({
all: true,
colors: {
info: "blue",
error: "red",
warn: "yellow",
},
}),
)
}

const config = {
format: winston.format.json(),
format: winston.format.combine(winston.format.timestamp(), format),
transports: [new winston.transports.Console()],
}
export const logger = winston.createLogger(config)
export const middleware = expressWinston.logger({ winstonInstance: logger })
export const middleware = expressWinston.logger({
winstonInstance: logger,
ignoreRoute: (req) => req.url.startsWith("/assets"),
ignoredRoutes: [
"/theme.css",
"/main.css",
"/content-layout.css",
"/style.css",
"/ory-small.svg",
"/favico.png",
],
})
48 changes: 44 additions & 4 deletions src/routes/500.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,61 @@
// Copyright © 2022 Ory Corp
// SPDX-License-Identifier: Apache-2.0
import { RouteRegistrator } from "../pkg"
import { logger, RouteRegistrator } from "../pkg"
import { UserErrorCard } from "@ory/elements-markup"
import { format } from "@redtea/format-axios-error"
import { NextFunction, Request, Response } from "express"

function formatRequest(req: Request) {
return {
headers: req.headers,
method: req.method,
url: req.url,
httpVersion: req.httpVersion,
body: req.body,
cookies: req.cookies,
path: req.path,
protocol: req.protocol,
query: req.query,
hostname: req.hostname,
ip: req.ip,
originalUrl: req.originalUrl,
params: req.params,
}
}

export const register500Route: RouteRegistrator = (app, createHelpers) => {
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error(err, err.stack)
let jsonError: string = ""
try {
const formattedError = format(err)

logger.error("An error occurred", {
error: formattedError,
req: formatRequest(req),
})
delete (formattedError as any).config
delete (formattedError as any).isAxiosError
jsonError = JSON.stringify(formattedError)
} catch (e) {
// This shouldn't happen, as the try block should not throw an error.
// But if it does, we log it and render the Error card with a generic error message.
// If this is removed, the server will crash if the error is not serializable.
logger.error("An error occurred while serializing the error", {
error: err,
req: formatRequest(req),
})
}
res.status(500).render("error", {
card: UserErrorCard({
title: "Internal Server Error",
cardImage: createHelpers?.(req, res).logoUrl,
backUrl: req.header("Referer") || "welcome",
error: {
id: "backend-error",
id: "interal_server_error",
error: {
...err,
message:
"An internal server error occurred. Please try again later.",
debug: JSON.parse(jsonError),
},
},
}),
Expand Down

0 comments on commit 93d540f

Please sign in to comment.