Skip to content

Commit 071d372

Browse files
committed
[fix] Handle throw error/redirect in +server.js
Fixes #5993
1 parent 7b305af commit 071d372

File tree

5 files changed

+59
-10
lines changed

5 files changed

+59
-10
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
Handle `throw error/redirect` in `+server.js`

packages/kit/src/runtime/server/endpoint.js

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { HttpError, Redirect } from '../../index/private.js';
12
import { check_method_names, method_not_allowed } from './utils.js';
23

34
/**
@@ -29,16 +30,29 @@ export async function render_endpoint(event, route) {
2930
return method_not_allowed(mod, method);
3031
}
3132

32-
const response = await handler(
33-
/** @type {import('types').RequestEvent<Record<string, any>>} */ (event)
34-
);
35-
36-
if (!(response instanceof Response)) {
37-
return new Response(
38-
`Invalid response from route ${event.url.pathname}: handler should return a Response object`,
39-
{ status: 500 }
33+
try {
34+
const response = await handler(
35+
/** @type {import('types').RequestEvent<Record<string, any>>} */ (event)
4036
);
41-
}
4237

43-
return response;
38+
if (!(response instanceof Response)) {
39+
return new Response(
40+
`Invalid response from route ${event.url.pathname}: handler should return a Response object`,
41+
{ status: 500 }
42+
);
43+
}
44+
45+
return response;
46+
} catch (error) {
47+
if (error instanceof HttpError) {
48+
return new Response(error.message, { status: error.status });
49+
} else if (error instanceof Redirect) {
50+
return new Response(undefined, {
51+
status: error.status,
52+
headers: { Location: error.location }
53+
});
54+
} else {
55+
throw error;
56+
}
57+
}
4458
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { error } from '@sveltejs/kit';
2+
3+
export function GET() {
4+
throw error(401, 'You shall not pass');
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { redirect } from '@sveltejs/kit';
2+
3+
export function GET() {
4+
throw redirect(302, '/');
5+
}

packages/kit/test/apps/basics/test/server.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,26 @@ test.describe('Errors', () => {
181181
'This is your custom error page saying: "Cannot read properties of undefined (reading \'toUpperCase\')"'
182182
);
183183
});
184+
185+
test('throw error(..) in endpoint', async ({ page, read_errors }) => {
186+
const res = await page.goto('/errors/endpoint-throw-error');
187+
188+
const error = read_errors('/errors/endpoint-throw-error');
189+
expect(error).toBe(undefined);
190+
191+
expect(await res?.text()).toBe('You shall not pass');
192+
expect(res?.status()).toBe(401);
193+
});
194+
195+
test('throw redirect(..) in endpoint', async ({ page, read_errors }) => {
196+
const res = await page.goto('/errors/endpoint-throw-redirect');
197+
expect(res?.status()).toBe(200); // redirects are opaque to the browser
198+
199+
const error = read_errors('/errors/endpoint-throw-redirect');
200+
expect(error).toBe(undefined);
201+
202+
expect(await page.textContent('h1')).toBe('the answer is 42');
203+
});
184204
});
185205

186206
test.describe('Load', () => {

0 commit comments

Comments
 (0)