Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: properly handle missing schema if route is not defined #6650

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions packages/beacon-node/src/api/rest/base.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {parse as parseQueryString} from "qs";
import {FastifyInstance, fastify} from "fastify";
import {FastifyInstance, FastifyRequest, fastify} from "fastify";
import {fastifyCors} from "@fastify/cors";
import bearerAuthPlugin from "@fastify/bearer-auth";
import {ErrorAborted, Gauge, Histogram, Logger} from "@lodestar/utils";
Expand Down Expand Up @@ -62,7 +62,7 @@ export class RestApiServer {
this.activeSockets = new HttpActiveSocketsTracker(server.server, metrics);

// To parse our ApiError -> statusCode
server.setErrorHandler((err, req, res) => {
server.setErrorHandler((err, _req, res) => {
if (err.validation) {
void res.status(400).send(err.validation);
} else {
Expand All @@ -83,19 +83,19 @@ export class RestApiServer {
// Log all incoming request to debug (before parsing). TODO: Should we hook latter in the lifecycle? https://www.fastify.io/docs/latest/Lifecycle/
// Note: Must be an async method so fastify can continue the release lifecycle. Otherwise we must call done() or the request stalls
server.addHook("onRequest", async (req, _res) => {
const operationId = req.routeSchema.operationId as string;
const operationId = getOperationId(req);
this.logger.debug(`Req ${req.id} ${req.ip} ${operationId}`);
metrics?.requests.inc({operationId});
});

server.addHook("preHandler", async (req, _res) => {
const operationId = req.routeSchema.operationId as string;
const operationId = getOperationId(req);
this.logger.debug(`Exec ${req.id} ${req.ip} ${operationId}`);
});

// Log after response
server.addHook("onResponse", async (req, res) => {
const operationId = req.routeSchema.operationId as string;
const operationId = getOperationId(req);
this.logger.debug(`Res ${req.id} ${operationId} - ${res.raw.statusCode}`);
metrics?.responseTime.observe({operationId}, res.elapsedTime / 1000);
});
Expand All @@ -105,7 +105,7 @@ export class RestApiServer {
// Don't log NodeISSyncing errors, they happen very frequently while syncing and the validator polls duties
if (err instanceof ErrorAborted || err instanceof NodeIsSyncing) return;

const operationId = req.routeSchema.operationId as string;
const operationId = getOperationId(req);

if (err instanceof ApiError) {
this.logger.warn(`Req ${req.id} ${operationId} failed`, {reason: err.message});
Expand Down Expand Up @@ -157,3 +157,8 @@ export class RestApiServer {
return false;
}
}

function getOperationId(req: FastifyRequest): string {
// Note: `schema` will be `undefined` if route is not defined
return req.routeOptions.schema?.operationId ?? "unknown";
}
Loading