diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index 42787442a60b8..ed4ab57806e2b 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -632,6 +632,9 @@ export default class DevServer extends Server { ) return result } catch (error) { + if (error instanceof DecodeError) { + throw error + } this.logErrorWithOriginalStack(error, undefined, 'edge-server') const preflight = diff --git a/packages/next/server/next-server.ts b/packages/next/server/next-server.ts index 7b25d1deb59aa..02184f2f3c923 100644 --- a/packages/next/server/next-server.ts +++ b/packages/next/server/next-server.ts @@ -2,7 +2,7 @@ import './node-polyfill-fetch' import './node-polyfill-web-streams' import type { Route } from './router' -import type { CacheFs } from '../shared/lib/utils' +import { CacheFs, DecodeError, execOnce } from '../shared/lib/utils' import type { MiddlewareManifest } from '../build/webpack/plugins/middleware-plugin' import type RenderResult from './render-result' import type { FetchEventResult } from './web/types' @@ -18,8 +18,6 @@ import type { Params } from '../shared/lib/router/utils/route-matcher' import fs from 'fs' import { join, relative, resolve, sep } from 'path' import { IncomingMessage, ServerResponse } from 'http' - -import { execOnce } from '../shared/lib/utils' import { addRequestMeta, getRequestMeta } from './request-meta' import { @@ -1252,6 +1250,12 @@ export default class NextNodeServer extends BaseServer { return { finished: true } } + if (err instanceof DecodeError) { + res.statusCode = 400 + this.renderError(err, req, res, parsed.pathname || '') + return { finished: true } + } + const error = getProperError(err) console.error(error) res.statusCode = 500 diff --git a/test/integration/middleware-general/test/index.test.js b/test/integration/middleware-general/test/index.test.js index 9a10010b50105..ebfd1106feb98 100644 --- a/test/integration/middleware-general/test/index.test.js +++ b/test/integration/middleware-general/test/index.test.js @@ -27,6 +27,7 @@ describe('Middleware Runtime', () => { describe('dev mode', () => { afterAll(() => killApp(context.app)) beforeAll(async () => { + context.dev = true context.appPort = await findPort() context.app = await launchApp(context.appDir, context.appPort, { env: { @@ -87,6 +88,7 @@ describe('Middleware Runtime', () => { stderr: build.stderr, stdout: build.stdout, } + context.dev = false context.appPort = await findPort() context.app = await nextStart(context.appDir, context.appPort, { @@ -133,6 +135,15 @@ describe('Middleware Runtime', () => { }) function tests(context, locale = '') { + it('should respond with 400 on decode failure', async () => { + const res = await fetchViaHTTP(context.appPort, `${locale}/%2`) + expect(res.status).toBe(400) + + if (!context.dev) { + expect(await res.text()).toContain('Bad Request') + } + }) + it('should set fetch user agent correctly', async () => { const res = await fetchViaHTTP( context.appPort,