- Add a centralized not-found handler returning a consistent 404 response - Assert the expected error payload for unknown endpoints
81 lines
1.6 KiB
TypeScript
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();
|
|
}
|