report errors to sentry
This commit is contained in:
106
server/index.ts
Normal file
106
server/index.ts
Normal file
@ -0,0 +1,106 @@
|
||||
import express from "express";
|
||||
import compression from "compression";
|
||||
import morgan from "morgan";
|
||||
import { createRequestHandler } from "@remix-run/express";
|
||||
import * as Sentry from "@sentry/node";
|
||||
|
||||
import config from "~/config/config.server";
|
||||
import logger from "~/utils/logger.server";
|
||||
import { adminMiddleware, setupBullBoard } from "./queues";
|
||||
import { registerSentry, sentryLoadContext } from "./sentry-remix";
|
||||
|
||||
Sentry.init({
|
||||
dsn: config.sentry.dsn,
|
||||
integrations: [new Sentry.Integrations.Http({ tracing: true })],
|
||||
tracesSampleRate: 1.0,
|
||||
environment: process.env.NODE_ENV,
|
||||
});
|
||||
|
||||
const app = express();
|
||||
app.use((req, res, next) => {
|
||||
res.set("X-Fly-Region", process.env.FLY_REGION ?? "unknown");
|
||||
res.set("Strict-Transport-Security", `max-age=31536000; preload`);
|
||||
next();
|
||||
});
|
||||
|
||||
// replay non-GET/HEAD/OPTIONS requests to the primary Fly.io region rather than read-only Postgres instances
|
||||
// learn more: https://fly.io/docs/getting-started/multi-region-databases/#replay-the-request
|
||||
app.all("*", (req, res, next) => {
|
||||
const { method, path: pathname } = req;
|
||||
const { PRIMARY_REGION, FLY_REGION } = process.env;
|
||||
const isMethodReplayable = !["GET", "OPTIONS", "HEAD"].includes(method);
|
||||
const isReadOnlyRegion = FLY_REGION && PRIMARY_REGION && FLY_REGION !== PRIMARY_REGION;
|
||||
const shouldReplay = isMethodReplayable && isReadOnlyRegion;
|
||||
|
||||
if (!shouldReplay) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const logInfo = {
|
||||
pathname,
|
||||
method,
|
||||
PRIMARY_REGION,
|
||||
FLY_REGION,
|
||||
};
|
||||
logger.info("Replaying:", logInfo);
|
||||
res.set("fly-replay", `region=${PRIMARY_REGION}`);
|
||||
return res.sendStatus(409);
|
||||
});
|
||||
|
||||
app.disable("x-powered-by");
|
||||
app.use(
|
||||
compression({
|
||||
filter(req, res) {
|
||||
const contentTypeHeader = res.getHeader("Content-Type");
|
||||
let contentType = "";
|
||||
if (contentTypeHeader) {
|
||||
if (Array.isArray(contentTypeHeader)) {
|
||||
contentType = contentTypeHeader.join(" ");
|
||||
} else {
|
||||
contentType = String(contentTypeHeader);
|
||||
}
|
||||
}
|
||||
|
||||
if (contentType.includes("text/event-stream")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
// cache static and immutable assets
|
||||
app.use(express.static("public", { immutable: true, maxAge: "1y" }));
|
||||
|
||||
// setup background queues and cron jobs
|
||||
app.use("/admin", adminMiddleware);
|
||||
app.use("/admin/queues", setupBullBoard().getRouter());
|
||||
|
||||
app.use(morgan("tiny"));
|
||||
|
||||
app.all("*", (req, res, next) => {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
purgeRequireCache();
|
||||
}
|
||||
|
||||
return createRequestHandler({
|
||||
build: registerSentry(require("../build")),
|
||||
mode: process.env.NODE_ENV,
|
||||
getLoadContext: sentryLoadContext,
|
||||
})(req, res, next);
|
||||
});
|
||||
|
||||
const port = process.env.PORT || 3000;
|
||||
app.listen(port, () => {
|
||||
logger.info(`Server listening on port ${port}`);
|
||||
});
|
||||
|
||||
function purgeRequireCache() {
|
||||
const resolved = require.resolve("../build");
|
||||
for (const key in require.cache) {
|
||||
if (key.startsWith(resolved)) {
|
||||
delete require.cache[key];
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user