From ed87f150d1bc860712f467def1cc341322273d36 Mon Sep 17 00:00:00 2001 From: Matthew Little Date: Tue, 12 Nov 2024 11:47:44 +0100 Subject: [PATCH 1/2] chore: more details in event-observer http server logging (#2160) * fix: more details in event-observer http server logging * chore: misc cleanup --- src/event-stream/event-server.ts | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/event-stream/event-server.ts b/src/event-stream/event-server.ts index 2a2154b73..64fbf4f45 100644 --- a/src/event-stream/event-server.ts +++ b/src/event-stream/event-server.ts @@ -757,10 +757,32 @@ export async function startEventServer(opts: { } const bodyLimit = 1_000_000 * 500; // 500MB body limit + + const reqLogSerializer = (req: FastifyRequest) => ({ + method: req.method, + url: req.url, + version: req.headers?.['accept-version'] as string, + hostname: req.hostname, + remoteAddress: req.ip, + remotePort: req.socket?.remotePort, + bodySize: parseInt(req.headers?.['content-length'] as string) || 'unknown', + }); + const loggerOpts: FastifyServerOptions['logger'] = { ...PINO_LOGGER_CONFIG, name: 'stacks-node-event', + serializers: { + req: reqLogSerializer, + res: reply => ({ + statusCode: reply.statusCode, + method: reply.request?.method, + url: reply.request?.url, + requestBodySize: parseInt(reply.request?.headers['content-length'] as string) || 'unknown', + responseBodySize: parseInt(reply.getHeader?.('content-length') as string) || 'unknown', + }), + }, }; + const app = Fastify({ bodyLimit, trustProxy: true, @@ -768,6 +790,18 @@ export async function startEventServer(opts: { ignoreTrailingSlash: true, }); + app.addHook('onRequest', (req, reply, done) => { + req.raw.on('close', () => { + if (req.raw.aborted) { + req.log.warn( + reqLogSerializer(req), + `Request was aborted by the client: ${req.method} ${req.url}` + ); + } + }); + done(); + }); + const handleRawEventRequest = async (req: FastifyRequest) => { await messageHandler.handleRawEventRequest(req.url, req.body, db); From b17895b93bd4ec70a4d623c7064d148e58b0470e Mon Sep 17 00:00:00 2001 From: Matthew Little Date: Tue, 12 Nov 2024 11:48:27 +0100 Subject: [PATCH 2/2] docs: default 4xx error schemas for all routes (#2159) --- .vscode/launch.json | 7 +++++++ src/api/schemas/responses/responses.ts | 3 ++- src/openapi-generator.ts | 13 ++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 1a90b38bb..72a01bd2f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -460,6 +460,13 @@ "TS_NODE_SKIP_IGNORE": "true" } }, + { + "type": "node", + "request": "launch", + "name": "docs: openapi-generator", + "runtimeArgs": ["-r", "ts-node/register/transpile-only"], + "args": ["${workspaceFolder}/src/openapi-generator.ts"] + }, { "type": "node", "request": "launch", diff --git a/src/api/schemas/responses/responses.ts b/src/api/schemas/responses/responses.ts index 160075d42..9903fdcc1 100644 --- a/src/api/schemas/responses/responses.ts +++ b/src/api/schemas/responses/responses.ts @@ -17,8 +17,9 @@ import { NakamotoBlockSchema, SignerSignatureSchema } from '../entities/block'; export const ErrorResponseSchema = Type.Object( { error: Type.String(), + message: Type.Optional(Type.String()), }, - { title: 'Error Response' } + { title: 'Error Response', additionalProperties: true } ); export const ServerStatusResponseSchema = Type.Object( diff --git a/src/openapi-generator.ts b/src/openapi-generator.ts index 817e2492d..94ec7b537 100644 --- a/src/openapi-generator.ts +++ b/src/openapi-generator.ts @@ -1,9 +1,10 @@ import Fastify from 'fastify'; -import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; +import { TSchema, TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; import FastifySwagger from '@fastify/swagger'; import { writeFileSync } from 'fs'; import { OpenApiSchemaOptions } from './api/schemas/openapi'; import { StacksApiRoutes } from './api/init'; +import { ErrorResponseSchema } from './api/schemas/responses/responses'; /** * Generates `openapi.yaml` based on current Swagger definitions. @@ -14,6 +15,16 @@ async function generateOpenApiFiles() { logger: true, }).withTypeProvider(); + // If a response schema is defined but lacks a '4xx' response, add it + fastify.addHook( + 'onRoute', + (route: { schema?: { response: Record } }) => { + if (route.schema?.response && !route.schema?.response['4xx']) { + route.schema.response['4xx'] = ErrorResponseSchema; + } + } + ); + await fastify.register(FastifySwagger, OpenApiSchemaOptions); await fastify.register(StacksApiRoutes); await fastify.ready();