orThrow, orUnauthorized
Wrap an API call in a loader: orThrow turns any failure into a not-found error, orUnauthorized turns a 401 or 403 into the unauthorized flow.
import { orThrow, orUnauthorized } from '@salla.sa/twilight-theme-engine/providers';In plain words
API calls fail: a product was deleted, the server had a bad moment, a customer's session expired. Wrapping the call decides what the visitor sees instead of a crash.
await orThrow(product.find(id)) gives you the product, or a clean not-found page. await orUnauthorized(order.find(id)) gives you the order, or the unauthorized page when the API says the customer is not signed in; any other failure is left for you to handle.
Signature
function orThrow<T>(promise: Promise<T>): Promise<T>
// on any rejection: console.debug('[loader error]', error), then throw new NotFoundError()
function orUnauthorized<T>(promise: Promise<T>): Promise<T>
// rejection whose error.response.status is 401 or 403: throw unauthorized()
// any other rejection is rethrown unchangedTry it live
await orThrow(request that fails: HTTP 500) → running…
import { orThrow } from '@salla.sa/twilight-theme-engine/providers';
import { product } from '@salla.sa/twilight-theme-engine/api/product';
// Any failure (missing, 500, offline) becomes a 404 page instead of a crash.
export async function loader({ params }: { params: { id: string } }) {
return { product: await orThrow(product.find(params.id)) };
}
Example
import { orUnauthorized } from '@salla.sa/twilight-theme-engine/providers';
import { order } from '@salla.sa/twilight-theme-engine/api/order';
export async function loader({ params }: { params: { id: string } }) {
return { order: await orUnauthorized(order.find(params.id)) };
}
How it behaves
The engine uses both:
product.findOrThrowisorThrow(product.find(id)),order.findOrThrowisorUnauthorized(order.find(id)), and the orders, wallet, wishlist and notifications loaders wrap their calls inorUnauthorized.orUnauthorizedreadserror.response.status, the shape of the engine API client's HTTP errors.
Gotchas
orThrowthrowsnew NotFoundError()directly, not the adaptednotFound(): under TanStack Router it reaches the route's error component (the default one renders a 404ErrorPagefor it), not the not-found component. A customerrorComponentmust recogniseNotFoundErroritself.orThrowreports every failure, a network error or a 500 included, as "not found", keeping the original only in aconsole.debugline. Use it where "this does not exist" is the honest answer.A rejection without
response, such as a plainfetchnetwork error, passes throughorUnauthorizedunchanged.
Related
Throw helpers for route loaders: stop and show the not-found page, send the visitor to another address, or refuse a guest.
NotFoundError, RedirectError, UnauthorizedErrorThe error classes behind the loader helpers, so an error screen can tell a missing page, a redirect and a refused guest apart.
Source and docs
- Engine source:
packages/theme-engine/src/providers/NavigationProvider.ts