From 8b912380212386ac2b95e3f5ff906125065251d8 Mon Sep 17 00:00:00 2001 From: Beth Griggs Date: Tue, 8 Jul 2025 17:33:19 +0100 Subject: [PATCH 1/4] feat(http): support server-level timeout and socket options via app-config Adds support for configuring server-level HTTP options through the `app-config.yaml` file under the `backend.server` key. This includes support for: `headersTimeout`, `keepAliveTimeout`, `requestTimeout`, `timeout`, `maxHeadersCount`, and `maxRequestsPerSocket`. These options are passed directly to the underlying Node.js HTTP server, when omitted, the default values are used. Refs: https://github.com/backstage/backstage/issues/21808 Refs: https://github.com/backstage/backstage/issues/30449 Signed-off-by: Beth Griggs --- .changeset/salty-words-wash.md | 11 ++++ .../core-services/root-http-router.md | 8 +++ .../rootHttpRouter/http/config.test.ts | 53 +++++++++++++++++++ .../entrypoints/rootHttpRouter/http/config.ts | 30 +++++++++++ .../rootHttpRouter/http/createHttpServer.ts | 29 ++++++++-- .../entrypoints/rootHttpRouter/http/types.ts | 8 +++ 6 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 .changeset/salty-words-wash.md diff --git a/.changeset/salty-words-wash.md b/.changeset/salty-words-wash.md new file mode 100644 index 0000000000..eec2e85331 --- /dev/null +++ b/.changeset/salty-words-wash.md @@ -0,0 +1,11 @@ +--- +'@backstage/backend-defaults': minor +--- + +Adds support for configuring server-level HTTP options through the +`app-config.yaml` file under the `backend.server` key. Supported options +include `headersTimeout`, `keepAliveTimeout`, `requestTimeout`, `timeout`, +`maxHeadersCount`, and `maxRequestsPerSocket`. + +These are passed directly to the underlying Node.js HTTP server. +If omitted, Node.js defaults are used. diff --git a/docs/backend-system/core-services/root-http-router.md b/docs/backend-system/core-services/root-http-router.md index 1e76fb1871..0ced7aac66 100644 --- a/docs/backend-system/core-services/root-http-router.md +++ b/docs/backend-system/core-services/root-http-router.md @@ -65,6 +65,14 @@ backend: # - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M'. # - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }`. serverShutdownDelay: { seconds: 20 } + server: + # (Optional) HTTP server configuration, Node.js defaults apply otherwise + headersTimeout: 60000 + keepAliveTimeout: 5000 + maxHeadersCount: 2000 + maxRequestsPerSocket: 100 + requestTimeout: 30000 + timeout: 30000 ``` ### Via Code diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts index 577bae08f3..0fa9dc0420 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts @@ -61,6 +61,59 @@ describe('readHttpServerOptions', () => { expect(readHttpServerOptions(new ConfigReader(input))).toEqual(output); }); + it.each([ + [ + { + server: { + headersTimeout: 10000, + requestTimeout: 30000, + keepAliveTimeout: 5000, + timeout: 60000, + maxHeadersCount: 1000, + maxRequestsPerSocket: 100, + }, + }, + { + listen: { host: '', port: 7007 }, + https: undefined, + serverOptions: { + headersTimeout: 10000, + requestTimeout: 30000, + keepAliveTimeout: 5000, + timeout: 60000, + maxHeadersCount: 1000, + maxRequestsPerSocket: 100, + }, + }, + ], + [ + { + server: { + keepAliveTimeout: 8000, + timeout: 30000, + }, + }, + { + listen: { host: '', port: 7007 }, + https: undefined, + serverOptions: { + keepAliveTimeout: 8000, + timeout: 30000, + }, + }, + ], + [ + { server: {} }, + { + listen: { host: '', port: 7007 }, + https: undefined, + serverOptions: undefined, + }, + ], + ])('should read server options %#', (input, output) => { + expect(readHttpServerOptions(new ConfigReader(input))).toEqual(output); + }); + it.each([ [ { listen: { port: 'not-a-number' } }, diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts index ec29a8a044..229ba2d78d 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts @@ -38,6 +38,7 @@ export function readHttpServerOptions(config?: Config): HttpServerOptions { return { listen: readHttpListenOptions(config), https: readHttpsOptions(config), + serverOptions: readServerOptions(config), }; } @@ -99,3 +100,32 @@ function readHttpsOptions(config?: Config): HttpServerOptions['https'] { }, }; } + +function readServerOptions( + config?: Config, +): HttpServerOptions['serverOptions'] { + const serverConfig = config?.getOptionalConfig('server'); + if (!serverConfig) { + return undefined; + } + + const serverOptions: HttpServerOptions['serverOptions'] = {}; + + const keys = [ + 'headersTimeout', + 'requestTimeout', + 'keepAliveTimeout', + 'timeout', + 'maxHeadersCount', + 'maxRequestsPerSocket', + ] as const; + + for (const key of keys) { + const value = serverConfig.getOptionalNumber(key); + if (value !== undefined) { + serverOptions[key] = value; + } + } + + return Object.keys(serverOptions).length === 0 ? undefined : serverOptions; +} diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts index fbb6ac5805..1ae6cc4fd1 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts @@ -84,6 +84,8 @@ async function createServer( options: HttpServerOptions, deps: { logger: LoggerService }, ): Promise { + let server: http.Server; + if (options.https) { const { certificate } = options.https; if (certificate.type === 'generated') { @@ -91,10 +93,31 @@ async function createServer( certificate.hostname, deps.logger, ); - return https.createServer(credentials, listener); + server = https.createServer(credentials, listener); + } else { + server = https.createServer(certificate, listener); } - return https.createServer(certificate, listener); + } else { + server = http.createServer(listener); } - return http.createServer(listener); + // apply custom server options + if (options.serverOptions) { + const { serverOptions } = options; + + if (serverOptions.headersTimeout !== undefined) + server.headersTimeout = serverOptions.headersTimeout; + if (serverOptions.requestTimeout !== undefined) + server.requestTimeout = serverOptions.requestTimeout; + if (serverOptions.keepAliveTimeout !== undefined) + server.keepAliveTimeout = serverOptions.keepAliveTimeout; + if (serverOptions.timeout !== undefined) + server.timeout = serverOptions.timeout; + if (serverOptions.maxHeadersCount !== undefined) + server.maxHeadersCount = serverOptions.maxHeadersCount; + if (serverOptions.maxRequestsPerSocket !== undefined) + server.maxRequestsPerSocket = serverOptions.maxRequestsPerSocket; + } + + return server; } diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts index 2298ef11ff..13e7914c03 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts @@ -42,6 +42,14 @@ export type HttpServerOptions = { https?: { certificate: HttpServerCertificateOptions; }; + serverOptions?: { + headersTimeout?: number; + requestTimeout?: number; + keepAliveTimeout?: number; + timeout?: number; + maxHeadersCount?: number; + maxRequestsPerSocket?: number; + }; }; /** From ee06f7d181166a06c03659c56c9e4f0a00b23a28 Mon Sep 17 00:00:00 2001 From: Beth Griggs Date: Wed, 9 Jul 2025 16:49:38 +0100 Subject: [PATCH 2/4] fixup! add API report Signed-off-by: Beth Griggs --- packages/backend-defaults/report-rootHttpRouter.api.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/backend-defaults/report-rootHttpRouter.api.md b/packages/backend-defaults/report-rootHttpRouter.api.md index 84424be39d..acabea9640 100644 --- a/packages/backend-defaults/report-rootHttpRouter.api.md +++ b/packages/backend-defaults/report-rootHttpRouter.api.md @@ -82,6 +82,14 @@ export type HttpServerOptions = { https?: { certificate: HttpServerCertificateOptions; }; + serverOptions?: { + headersTimeout?: number; + requestTimeout?: number; + keepAliveTimeout?: number; + timeout?: number; + maxHeadersCount?: number; + maxRequestsPerSocket?: number; + }; }; // @public From d501e8c7686500428b008d869a6297cceb464bff Mon Sep 17 00:00:00 2001 From: Beth Griggs Date: Fri, 12 Sep 2025 15:55:49 +0100 Subject: [PATCH 3/4] feat(http): move HTTP server configuration application, enable flexible duration formats This commit applies HTTP server configuration in `rootHttpRouterServiceFactory` and adds support for multiple duration formats for timeouts. The previous tests for server config have been moved and refactored. The documentation and CHANGELOG have been updated to reflect the new configuration structure and supported formats. Signed-off-by: Beth Griggs --- .../core-services/root-http-router.md | 12 ++- packages/backend-defaults/config.d.ts | 25 ++++++ .../report-rootHttpRouter.api.md | 8 -- .../rootHttpRouter/http/config.test.ts | 53 ------------- .../entrypoints/rootHttpRouter/http/config.ts | 30 -------- .../rootHttpRouter/http/createHttpServer.ts | 29 +------ .../entrypoints/rootHttpRouter/http/types.ts | 8 -- .../rootHttpRouterServiceFactory.test.ts | 61 +++++++++++++++ .../rootHttpRouterServiceFactory.ts | 77 +++++++++++++++++++ 9 files changed, 175 insertions(+), 128 deletions(-) diff --git a/docs/backend-system/core-services/root-http-router.md b/docs/backend-system/core-services/root-http-router.md index 0ced7aac66..1bda95a990 100644 --- a/docs/backend-system/core-services/root-http-router.md +++ b/docs/backend-system/core-services/root-http-router.md @@ -67,12 +67,18 @@ backend: serverShutdownDelay: { seconds: 20 } server: # (Optional) HTTP server configuration, Node.js defaults apply otherwise + # Timeout values support multiple formats: + # - Numbers (milliseconds): 30000 + # - Duration strings: '30s', '1 minute', '2 hours' + # - ISO duration strings: 'PT30S', 'PT1M', 'PT2H' + # - Duration objects: { seconds: 30 }, { minutes: 1 }, { hours: 2 } headersTimeout: 60000 - keepAliveTimeout: 5000 + requestTimeout: '30s' + keepAliveTimeout: { seconds: 5 } + timeout: 'PT30S' + # Numeric-only settings maxHeadersCount: 2000 maxRequestsPerSocket: 100 - requestTimeout: 30000 - timeout: 30000 ``` ### Via Code diff --git a/packages/backend-defaults/config.d.ts b/packages/backend-defaults/config.d.ts index 2982557f32..f0632a37bb 100644 --- a/packages/backend-defaults/config.d.ts +++ b/packages/backend-defaults/config.d.ts @@ -95,6 +95,31 @@ export interface Config { }; }; + /** + * Server-level HTTP options configuration for the backend. + * These options are passed directly to the underlying Node.js HTTP server. + * + * Timeout values support multiple formats: + * - A number in milliseconds + * - A string in the format of '1d', '2 seconds' etc. as supported by the `ms` library + * - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M' + * - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }` + */ + server?: { + /** Sets the timeout value for receiving the complete HTTP headers from the client. */ + headersTimeout?: number | string | HumanDuration; + /** Sets the timeout value for receiving the entire request (headers and body) from the client. */ + requestTimeout?: number | string | HumanDuration; + /** Sets the timeout value for inactivity on a socket during keep-alive. */ + keepAliveTimeout?: number | string | HumanDuration; + /** Sets the timeout value for sockets. */ + timeout?: number | string | HumanDuration; + /** Limits maximum incoming headers count. */ + maxHeadersCount?: number; + /** Sets the maximum number of requests socket can handle before closing keep alive connection. */ + maxRequestsPerSocket?: number; + }; + /** * Options used by the default auditor service. */ diff --git a/packages/backend-defaults/report-rootHttpRouter.api.md b/packages/backend-defaults/report-rootHttpRouter.api.md index acabea9640..84424be39d 100644 --- a/packages/backend-defaults/report-rootHttpRouter.api.md +++ b/packages/backend-defaults/report-rootHttpRouter.api.md @@ -82,14 +82,6 @@ export type HttpServerOptions = { https?: { certificate: HttpServerCertificateOptions; }; - serverOptions?: { - headersTimeout?: number; - requestTimeout?: number; - keepAliveTimeout?: number; - timeout?: number; - maxHeadersCount?: number; - maxRequestsPerSocket?: number; - }; }; // @public diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts index 0fa9dc0420..577bae08f3 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts @@ -61,59 +61,6 @@ describe('readHttpServerOptions', () => { expect(readHttpServerOptions(new ConfigReader(input))).toEqual(output); }); - it.each([ - [ - { - server: { - headersTimeout: 10000, - requestTimeout: 30000, - keepAliveTimeout: 5000, - timeout: 60000, - maxHeadersCount: 1000, - maxRequestsPerSocket: 100, - }, - }, - { - listen: { host: '', port: 7007 }, - https: undefined, - serverOptions: { - headersTimeout: 10000, - requestTimeout: 30000, - keepAliveTimeout: 5000, - timeout: 60000, - maxHeadersCount: 1000, - maxRequestsPerSocket: 100, - }, - }, - ], - [ - { - server: { - keepAliveTimeout: 8000, - timeout: 30000, - }, - }, - { - listen: { host: '', port: 7007 }, - https: undefined, - serverOptions: { - keepAliveTimeout: 8000, - timeout: 30000, - }, - }, - ], - [ - { server: {} }, - { - listen: { host: '', port: 7007 }, - https: undefined, - serverOptions: undefined, - }, - ], - ])('should read server options %#', (input, output) => { - expect(readHttpServerOptions(new ConfigReader(input))).toEqual(output); - }); - it.each([ [ { listen: { port: 'not-a-number' } }, diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts index 229ba2d78d..ec29a8a044 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts @@ -38,7 +38,6 @@ export function readHttpServerOptions(config?: Config): HttpServerOptions { return { listen: readHttpListenOptions(config), https: readHttpsOptions(config), - serverOptions: readServerOptions(config), }; } @@ -100,32 +99,3 @@ function readHttpsOptions(config?: Config): HttpServerOptions['https'] { }, }; } - -function readServerOptions( - config?: Config, -): HttpServerOptions['serverOptions'] { - const serverConfig = config?.getOptionalConfig('server'); - if (!serverConfig) { - return undefined; - } - - const serverOptions: HttpServerOptions['serverOptions'] = {}; - - const keys = [ - 'headersTimeout', - 'requestTimeout', - 'keepAliveTimeout', - 'timeout', - 'maxHeadersCount', - 'maxRequestsPerSocket', - ] as const; - - for (const key of keys) { - const value = serverConfig.getOptionalNumber(key); - if (value !== undefined) { - serverOptions[key] = value; - } - } - - return Object.keys(serverOptions).length === 0 ? undefined : serverOptions; -} diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts index 1ae6cc4fd1..fbb6ac5805 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts @@ -84,8 +84,6 @@ async function createServer( options: HttpServerOptions, deps: { logger: LoggerService }, ): Promise { - let server: http.Server; - if (options.https) { const { certificate } = options.https; if (certificate.type === 'generated') { @@ -93,31 +91,10 @@ async function createServer( certificate.hostname, deps.logger, ); - server = https.createServer(credentials, listener); - } else { - server = https.createServer(certificate, listener); + return https.createServer(credentials, listener); } - } else { - server = http.createServer(listener); + return https.createServer(certificate, listener); } - // apply custom server options - if (options.serverOptions) { - const { serverOptions } = options; - - if (serverOptions.headersTimeout !== undefined) - server.headersTimeout = serverOptions.headersTimeout; - if (serverOptions.requestTimeout !== undefined) - server.requestTimeout = serverOptions.requestTimeout; - if (serverOptions.keepAliveTimeout !== undefined) - server.keepAliveTimeout = serverOptions.keepAliveTimeout; - if (serverOptions.timeout !== undefined) - server.timeout = serverOptions.timeout; - if (serverOptions.maxHeadersCount !== undefined) - server.maxHeadersCount = serverOptions.maxHeadersCount; - if (serverOptions.maxRequestsPerSocket !== undefined) - server.maxRequestsPerSocket = serverOptions.maxRequestsPerSocket; - } - - return server; + return http.createServer(listener); } diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts index 13e7914c03..2298ef11ff 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts @@ -42,14 +42,6 @@ export type HttpServerOptions = { https?: { certificate: HttpServerCertificateOptions; }; - serverOptions?: { - headersTimeout?: number; - requestTimeout?: number; - keepAliveTimeout?: number; - timeout?: number; - maxHeadersCount?: number; - maxRequestsPerSocket?: number; - }; }; /** diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts index 0f2b6463e4..8f8d1b7656 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts @@ -323,4 +323,65 @@ describe('rootHttpRouterServiceFactory', () => { }), ).resolves.toBeUndefined(); }); + + it('should start successfully with server configuration options', async () => { + const { app } = await createExpressApp( + mockServices.rootConfig.factory({ + data: { + backend: { + listen: { port: 0 }, + server: { + headersTimeout: 30000, + requestTimeout: '45s', + keepAliveTimeout: 'PT1M', + timeout: { seconds: 120 }, + maxHeadersCount: 2000, + maxRequestsPerSocket: 100, + }, + }, + }, + }), + ); + + // Verify the server starts and responds to health checks + await request(app) + .get('/.backstage/health/v1/liveness') + .expect(200, { status: 'ok' }); + }); + + it('should start successfully with partial server configuration', async () => { + const { app } = await createExpressApp( + mockServices.rootConfig.factory({ + data: { + backend: { + listen: { port: 0 }, + server: { + headersTimeout: 60000, + maxHeadersCount: 1500, + }, + }, + }, + }), + ); + + await request(app) + .get('/.backstage/health/v1/liveness') + .expect(200, { status: 'ok' }); + }); + + it('should start successfully with no server configuration', async () => { + const { app } = await createExpressApp( + mockServices.rootConfig.factory({ + data: { + backend: { + listen: { port: 0 }, + }, + }, + }), + ); + + await request(app) + .get('/.backstage/health/v1/liveness') + .expect(200, { status: 'ok' }); + }); }); diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts index 3b50515742..1bbf986a98 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts @@ -117,6 +117,83 @@ const rootHttpRouterServiceFactoryWithOptions = ( if (trustProxy !== undefined) { app.set('trust proxy', trustProxy); } + + // Apply server-level HTTP options from config + const backendConfig = config.getOptionalConfig('backend'); + const serverConfig = backendConfig?.getOptionalConfig('server'); + + if (serverConfig) { + // Helper function to read duration values (supporting number, string, or HumanDuration) + const readDurationValue = (key: string): number | undefined => { + if (!serverConfig.has(key)) { + return undefined; + } + + const value = serverConfig.getOptional(key); + if (typeof value === 'number') { + return value; + } + + // If it's not a number, try to read it as a duration + try { + const duration = readDurationFromConfig(serverConfig, { key }); + return durationToMilliseconds(duration); + } catch (error) { + // Log warning for parsing failures + logger.warn( + `Failed to parse backend.server.${key} as duration: ${error}. ` + + `Expected a number (milliseconds), duration string (e.g., '30s'), ` + + `ISO duration (e.g., 'PT30S'), or duration object (e.g., {seconds: 30}). ` + + `Falling back to number parsing.`, + ); + // Fallback to reading as number if duration parsing fails + const fallbackValue = serverConfig.getOptionalNumber(key); + if (fallbackValue === undefined && typeof value === 'string') { + logger.error( + `backend.server.${key} value '${value}' could not be parsed as either ` + + `a duration or a number. This setting will be ignored.`, + ); + } + return fallbackValue; + } + }; + + // Apply timeout settings + const headersTimeout = readDurationValue('headersTimeout'); + if (headersTimeout !== undefined) { + server.headersTimeout = headersTimeout; + } + + const requestTimeout = readDurationValue('requestTimeout'); + if (requestTimeout !== undefined) { + server.requestTimeout = requestTimeout; + } + + const keepAliveTimeout = readDurationValue('keepAliveTimeout'); + if (keepAliveTimeout !== undefined) { + server.keepAliveTimeout = keepAliveTimeout; + } + + const timeout = readDurationValue('timeout'); + if (timeout !== undefined) { + server.timeout = timeout; + } + + // Apply numeric settings + const maxHeadersCount = + serverConfig.getOptionalNumber('maxHeadersCount'); + if (maxHeadersCount !== undefined) { + server.maxHeadersCount = maxHeadersCount; + } + + const maxRequestsPerSocket = serverConfig.getOptionalNumber( + 'maxRequestsPerSocket', + ); + if (maxRequestsPerSocket !== undefined) { + server.maxRequestsPerSocket = maxRequestsPerSocket; + } + } + app.use(middleware.helmet()); app.use(middleware.cors()); app.use(middleware.compression()); From 236d42720d56cafe31927a244fd48e72028152c6 Mon Sep 17 00:00:00 2001 From: Beth Griggs Date: Tue, 23 Sep 2025 15:25:31 +0100 Subject: [PATCH 4/4] fixup! remove fallback number parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Beth Griggs --- .../rootHttpRouter/rootHttpRouterServiceFactory.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts index 1bbf986a98..b0cc9d160e 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts @@ -146,15 +146,7 @@ const rootHttpRouterServiceFactoryWithOptions = ( `ISO duration (e.g., 'PT30S'), or duration object (e.g., {seconds: 30}). ` + `Falling back to number parsing.`, ); - // Fallback to reading as number if duration parsing fails - const fallbackValue = serverConfig.getOptionalNumber(key); - if (fallbackValue === undefined && typeof value === 'string') { - logger.error( - `backend.server.${key} value '${value}' could not be parsed as either ` + - `a duration or a number. This setting will be ignored.`, - ); - } - return fallbackValue; + return undefined; } };