diff --git a/test/integration/edge-runtime-streaming-error/pages/api/test.js b/test/integration/edge-runtime-streaming-error/pages/api/test.js new file mode 100644 index 0000000000000..b5d485fcd223a --- /dev/null +++ b/test/integration/edge-runtime-streaming-error/pages/api/test.js @@ -0,0 +1,14 @@ +export const config = { + runtime: 'experimental-edge', +} +export default function () { + return new Response( + new ReadableStream({ + start(ctr) { + ctr.enqueue(new TextEncoder().encode('hello')) + ctr.enqueue(true) + ctr.close() + }, + }) + ) +} diff --git a/test/integration/edge-runtime-streaming-error/test/index.test.ts b/test/integration/edge-runtime-streaming-error/test/index.test.ts new file mode 100644 index 0000000000000..1f25873dae63b --- /dev/null +++ b/test/integration/edge-runtime-streaming-error/test/index.test.ts @@ -0,0 +1,81 @@ +import stripAnsi from 'next/dist/compiled/strip-ansi' +import { + fetchViaHTTP, + findPort, + killApp, + launchApp, + nextBuild, + nextStart, + waitFor, +} from 'next-test-utils' +import path from 'path' +import { remove } from 'fs-extra' + +const appDir = path.join(__dirname, '..') + +function test(context: ReturnType) { + return async () => { + const res = await fetchViaHTTP(context.appPort, '/api/test') + expect(await res.text()).toEqual('hello') + expect(res.status).toBe(200) + await waitFor(200) + const santizedOutput = stripAnsi(context.output) + expect(santizedOutput).toMatch( + new RegExp(`TypeError: This ReadableStream did not return bytes.`, 'm') + ) + expect(santizedOutput).not.toContain('webpack-internal:') + } +} + +function createContext() { + const ctx = { + output: '', + appPort: -1, + app: undefined, + handler: { + onStdout(msg) { + this.output += msg + }, + onStderr(msg) { + this.output += msg + }, + }, + } + ctx.handler.onStderr = ctx.handler.onStderr.bind(ctx) + ctx.handler.onStdout = ctx.handler.onStdout.bind(ctx) + return ctx +} + +describe('dev mode', () => { + const context = createContext() + + beforeAll(async () => { + context.appPort = await findPort() + context.app = await launchApp(appDir, context.appPort, { + ...context.handler, + env: { __NEXT_TEST_WITH_DEVTOOL: 1 }, + }) + }) + + afterAll(() => killApp(context.app)) + + it('logs the error correctly', test(context)) +}) + +describe('production mode', () => { + const context = createContext() + + beforeAll(async () => { + await remove(path.join(appDir, '.next')) + await nextBuild(appDir, undefined, { + stderr: true, + stdout: true, + }) + context.appPort = await findPort() + context.app = await nextStart(appDir, context.appPort, { + ...context.handler, + }) + }) + afterAll(() => killApp(context.app)) + it('logs the error correctly', test(context)) +})