Skip to content
Merged
Show file tree
Hide file tree
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
5 changes: 5 additions & 0 deletions .changeset/ninety-planets-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

allow `HandleServerError` hook to access `getRequestEvent`
4 changes: 2 additions & 2 deletions packages/kit/src/runtime/app/server/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import('node:async_hooks')
});

/**
* Returns the current `RequestEvent`. Can be used inside `handle`, `load` and actions (and functions called by them).
* Returns the current `RequestEvent`. Can be used inside server hooks, server `load` functions, actions, and endpoints (and functions called by them).
*
* In environments without [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage), this must be called synchronously (i.e. not after an `await`).
* @since 2.20.0
Expand All @@ -25,7 +25,7 @@ export function getRequestEvent() {

if (!event) {
let message =
'Can only read the current request event inside functions invoked during `handle`, such as server `load` functions, actions, and server endpoints.';
'Can only read the current request event inside functions invoked during `handle`, such as server `load` functions, actions, endpoints, and other server hooks.';

if (!als) {
message +=
Expand Down
7 changes: 6 additions & 1 deletion packages/kit/src/runtime/server/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { HttpError } from '../control.js';
import { fix_stack_trace } from '../shared-server.js';
import { ENDPOINT_METHODS } from '../../constants.js';
import { escape_html } from '../../utils/escape.js';
import { with_event } from '../app/server/event.js';

/** @param {any} body */
export function is_pojo(body) {
Expand Down Expand Up @@ -107,7 +108,11 @@ export async function handle_error_and_jsonify(event, options, error) {
const status = get_status(error);
const message = get_message(error);

return (await options.hooks.handleError({ error, event, status, message })) ?? { message };
return (
(await with_event(event, () =>
options.hooks.handleError({ error, event, status, message })
)) ?? { message }
);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions packages/kit/test/apps/basics/src/hooks.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export const handleError = ({ event, error: e, status, message }) => {
errors[event.url.pathname] = error_to_pojo(error);
fs.writeFileSync('test/errors.json', JSON.stringify(errors));

if (event.url.pathname.startsWith('/get-request-event/')) {
const ev = getRequestEvent();
message = ev.locals.message;
}

return event.url.pathname.endsWith('404-fallback')
? undefined
: { message: `${error.message} (${status} ${message})` };
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
import { page } from '$app/state';
</script>

<h1>{page.error.message}</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const load = async () => {
throw new Error('Crashing now');
};
3 changes: 3 additions & 0 deletions packages/kit/test/apps/basics/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1544,5 +1544,8 @@ test.describe('getRequestEvent', () => {
await page.click('button');

expect(await page.textContent('h1')).toBe('from form: hello');

await page.goto('/get-request-event/with-error');
expect(await page.textContent('h1')).toBe('Crashing now (500 hello from hooks.server.js)');
});
});
2 changes: 1 addition & 1 deletion packages/kit/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2417,7 +2417,7 @@ declare module '$app/server' {
*/
export function read(asset: string): Response;
/**
* Returns the current `RequestEvent`. Can be used inside `handle`, `load` and actions (and functions called by them).
* Returns the current `RequestEvent`. Can be used inside server hooks, server `load` functions, actions, and endpoints (and functions called by them).
*
* In environments without [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage), this must be called synchronously (i.e. not after an `await`).
* @since 2.20.0
Expand Down