File size: 1,175 Bytes
e830ad4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { error, isActionFailure, isHttpError, isRedirect, type Action } from '@sveltejs/kit';
import { ReadOnlyError } from './ledger/errors';

const STORAGE_MESSAGE = 'Could not save — the storage backend is unavailable. Please try again.';
const READ_ONLY_MESSAGE = 'The app is temporarily read-only; try again in a couple of minutes.';

/**
 * Wraps every action so an unexpected throw (bucket down, disk read-only, scrypt overload)
 * surfaces as a 503 the user can act on instead of a bare 500. Redirects, HttpErrors and
 * `fail()` results are the action's own control flow and pass through untouched.
 */
export function guarded<T extends Record<string, Action<any, any, any>>>(actions: T): T {
	const wrapped: Record<string, Action<any, any, any>> = {};
	for (const [name, action] of Object.entries(actions)) {
		wrapped[name] = async (event) => {
			try {
				return await action(event);
			} catch (e) {
				if (isRedirect(e) || isHttpError(e) || isActionFailure(e)) throw e;
				if (e instanceof ReadOnlyError) error(503, READ_ONLY_MESSAGE);
				console.error('[action] storage failure', e);
				error(503, STORAGE_MESSAGE);
			}
		};
	}
	return wrapped as T;
}