diff --git a/package.json b/package.json index b49857f..3329720 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "dotenv-expand": "^10.0.0", "ethereum-multicall": "^2.15.0", "express": "^4.18.2", + "helmet": "^7.1.0", "ts-node": "^10.9.2", "viem": "2.7.15", "winston": "3.8.2", diff --git a/src/example.ts b/src/example.ts index d211301..a7cbc1e 100644 --- a/src/example.ts +++ b/src/example.ts @@ -26,12 +26,11 @@ if ( console.log("Configuring Sentry for Liquidator"); Sentry.init({ dsn: `https://${process.env.SENTRY_DSN0}@${process.env.SENTRY_DSN1}.ingest.sentry.io/${process.env.SENTRY_DSN2}`, - sampleRate: 0.1, - tracesSampleRate: 1, enabled: process.env.SENTRY_DSN0 !== undefined && process.env.SENTRY_DSN1 !== undefined && process.env.SENTRY_DSN2 !== undefined, + tracesSampleRate: 0.1, release: process.env.GIT_COMMIT_SHA || undefined, initialScope: { tags: { "chain_name": chain.name } }, }); diff --git a/src/index.ts b/src/index.ts index c7dcbf9..29e624b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,8 @@ import { fork } from "child_process"; -import express from "express"; +import express, { NextFunction, Request, Response } from "express"; import * as Sentry from "@sentry/node"; import { arbitrum, base, mainnet, optimism } from "viem/chains"; +import helmet from "helmet"; const port = process.env.PORT || 8080; const app = express(); @@ -15,16 +16,26 @@ if ( console.log("Configuring Sentry"); Sentry.init({ dsn: `https://${process.env.SENTRY_DSN0}@${process.env.SENTRY_DSN1}.ingest.sentry.io/${process.env.SENTRY_DSN2}`, - sampleRate: 0.1, - tracesSampleRate: 1, enabled: process.env.SENTRY_DSN0 !== undefined && process.env.SENTRY_DSN1 !== undefined && process.env.SENTRY_DSN2 !== undefined, + integrations: [ + new Sentry.Integrations.Http({ tracing: true }), + new Sentry.Integrations.Express({ app }), + ], release: process.env.GIT_COMMIT_SHA || undefined, + tracesSampleRate: 0.02, }); } +// Configure Middleware +app.use(Sentry.Handlers.requestHandler()); +app.use(Sentry.Handlers.tracingHandler()); +app.use(helmet()); +app.disable("x-powered-by"); +app.set("trust proxy", true); + const chains = [mainnet.id, optimism.id, arbitrum.id, base.id]; chains.forEach((chain) => { @@ -38,6 +49,21 @@ app.get("/liquidator_readiness_check", (req, res) => { res.send("OK"); }); +// Used after all other routes to catch any unhandled errors +app.use(Sentry.Handlers.errorHandler()); +// Catch 404 and send our own error message (instead of the default Express one) +// eslint-disable-next-line @typescript-eslint/no-unused-vars +app.use((_req: Request, res: Response, _next: NextFunction) => { + res.status(404).send("Not found"); +}); +// Catch all other errors and sennd our own error message (instead of the default Express one) +app.use( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + (_err: unknown, _req: Request, res: Response, _next: NextFunction) => { + res.status(500).send("Internal server error"); + } +); + const server = app.listen(port, () => { // eslint-disable-next-line no-console console.log(`Server is running on port ${port}`); diff --git a/yarn.lock b/yarn.lock index a175d8a..ff92276 100644 --- a/yarn.lock +++ b/yarn.lock @@ -952,6 +952,11 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +helmet@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-7.1.0.tgz#287279e00f8a3763d5dccbaf1e5ee39b8c3784ca" + integrity sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"