local-ai-platform/src/server.ts
Brandon Wolfgang 75bb74f5b3 fix: standardize API responses for unknown routes
- Add a centralized not-found handler returning a consistent 404 response
- Assert the expected error payload for unknown endpoints
2026-10-21 19:58:54 -05:00

81 lines
1.6 KiB
TypeScript

import Fastify, { type FastifyError } from "fastify";
import { z } from "zod";
const echoSchema = z.object({
message: z.string().min(1).max(500),
});
export const buildApp = () => {
const app = Fastify({
logger: true,
});
app.setErrorHandler((error: FastifyError, request, reply) => {
request.log.error(error);
const candidateStatusCode = error.statusCode ?? 500;
const statusCode =
candidateStatusCode >= 400 && candidateStatusCode < 500
? candidateStatusCode
: 500;
return reply.code(statusCode).send({
error: statusCode === 500 ? "Internal Server Error" : "Request Error",
});
});
app.setNotFoundHandler((_request, reply) => {
return reply.code(404).send({
error: "Not Found",
});
});
app.get("/health", async () => ({
status: "ok",
}));
app.get("/ready", async () => ({
status: "ready",
dependencies: {
ollama: "not-integrated",
},
}));
app.post("/echo", async (request, reply) => {
const result = echoSchema.safeParse(request.body);
if (!result.success) {
return reply.code(400).send({
error: "Invalid request body",
});
}
return {
message: result.data.message,
};
});
app.get("/test-error", async () => {
throw new Error("Sensitive internal detail");
});
return app;
};
const start = async () => {
const app = buildApp();
try {
await app.listen({
host: "127.0.0.1",
port: 3000,
});
} catch (error) {
app.log.error(error);
process.exit(1);
}
};
if (import.meta.url === `file://${process.argv[1]}`) {
void start();
}