Skip to content

Commit 8fa140e

Browse files
committed
feat: enhance server routing and error handling
- Introduce healthcheck route using Remix fetch-router for stable deployment checks. - Map /remix-test route for development with proper module loading. - Improve error handling in the request listener to catch unhandled fetch-router errors. - Update vitest configuration to align with the new structure.
1 parent d56f355 commit 8fa140e

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

server.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
} from "remix/node-fetch-server";
77
import { createRequestHandler } from "react-router";
88
import { createRouter } from "remix/fetch-router";
9+
import { route } from "remix/fetch-router/routes";
910
import { compression } from "remix/compression-middleware";
1011
import { staticFiles } from "remix/static-middleware";
1112
import { rateLimit, filteredLogger } from "./server/middleware.ts";
@@ -75,6 +76,10 @@ const router = createRouter({
7576
// ---------------------------------------------------------------------------
7677
// Remix 3 routes (remix/component) — explicit patterns win over the catch-all
7778
// ---------------------------------------------------------------------------
79+
const remixRoutes = route({
80+
healthcheck: "/healthcheck",
81+
});
82+
7883
async function loadRemixModule(path: string) {
7984
if (viteDevServer) {
8085
return viteDevServer.ssrLoadModule(path);
@@ -83,15 +88,31 @@ async function loadRemixModule(path: string) {
8388
return import(path);
8489
}
8590

86-
router.map("/remix-test", async () => {
87-
const mod = await loadRemixModule("./app/remix/test-route.tsx");
88-
return mod.default();
91+
// Keep healthcheck on a stable path during migration so deploy checks never
92+
// depend on the in-progress Remix route asset strategy.
93+
router.map(remixRoutes, {
94+
healthcheck() {
95+
return new Response("OK", {
96+
headers: {
97+
"Cache-Control": "no-store",
98+
"Content-Type": "text/plain; charset=utf-8",
99+
},
100+
});
101+
},
89102
});
90103

91-
router.map("/healthcheck", async (context) => {
92-
const mod = await loadRemixModule("./app/remix/routes/healthcheck.ts");
93-
return mod.default(context);
94-
});
104+
if (viteDevServer) {
105+
const devRemixRoutes = route({
106+
remixTest: "/remix-test",
107+
});
108+
109+
router.map(devRemixRoutes, {
110+
async remixTest() {
111+
const mod = await loadRemixModule("./app/remix/test-route.tsx");
112+
return mod.default();
113+
},
114+
});
115+
}
95116

96117
// All remaining requests are handled by React Router
97118
router.map("*", (context) => handleRequest(context.request));
@@ -156,7 +177,15 @@ if (viteDevServer) {
156177
} else {
157178
// In production, all requests go through the fetch-based router.
158179
const server = http.createServer(
159-
createRequestListener((request) => router.fetch(request)),
180+
createRequestListener((request) =>
181+
router.fetch(request).catch((error: unknown) => {
182+
console.error("Unhandled fetch-router error", error);
183+
return new Response("Internal Server Error", {
184+
status: 500,
185+
headers: { "Content-Type": "text/plain; charset=utf-8" },
186+
});
187+
}),
188+
),
160189
);
161190

162191
server.listen(port, () => {

vitest.config.mts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
/// <reference types="vitest" />
21
/// <reference types="vite/client" />
32

43
import fs from "node:fs";
54
import path from "node:path";
6-
import { defineConfig } from "vite";
5+
import { defineConfig } from "vitest/config";
76
import react from "@vitejs/plugin-react";
87
import tsconfigPaths from "vite-tsconfig-paths";
98
import dotenv from "dotenv";

0 commit comments

Comments
 (0)