Skip to content

Commit

Permalink
Add rethrowUnless utility and remove type assertions (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
manzt authored Feb 24, 2025
1 parent aec3e45 commit 21641bf
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
10 changes: 5 additions & 5 deletions src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { Readable } from "@zarrita/storage";
import type { ZarrPixelSource } from "./ZarrPixelSource";
import type { default as GridLayer, GridLayerProps, GridLoader } from "./gridLayer";
import { initLayerStateFromSource } from "./io";
import type { RedirectError } from "./utils";
import { RedirectError, rethrowUnless } from "./utils";

export interface ViewState {
zoom: number;
Expand Down Expand Up @@ -150,11 +150,11 @@ export const addImageAtom = atom(null, async (get, set, config: ImageLayerConfig
}
set(sourceInfoAtom, [...prevSourceInfo, { id, ...sourceData }]);
} catch (err) {
if ((err as Error).name === "RedirectError") {
let redirect = err as RedirectError;
set(redirectObjAtom, { message: redirect.message, url: redirect.url });
rethrowUnless(err, Error);
if (err instanceof RedirectError) {
set(redirectObjAtom, { message: err.message, url: err.url });
} else {
set(sourceErrorAtom, (err as Error).message);
set(sourceErrorAtom, err.message);
}
}
});
Expand Down
39 changes: 39 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,3 +447,42 @@ export function isMultiscales(attrs: zarr.Attributes): attrs is { multiscales: O
export function isBioformats2rawlayout(attrs: zarr.Attributes): attrs is { multiscales: Ome.Bioformats2rawlayout } {
return "bioformats2raw.layout" in attrs;
}

/**
* Ensures an error matches expected type(s), otherwise rethrows.
*
* Unmatched errors bubble up, like Python's `except`. Narrows error types for
* type-safe property access.
*
* Usage
* @example
* ```ts
* class DatabaseError extends Error {}
* class NetworkError extends Error {}
*
* try {
* await db.query();
* } catch (error) {
* rethrowUnless(error, DatabaseError, NetworkError);
* error; // DatabaseError | NetworkError
* }
* ```
*
* @param error - The error to check
* @param ErrorClasses - Expected error type(s)
* @throws The original error if it doesn't match expected type(s)
*
* @copyright Trevor Manz 2025
* @license MIT
* @see {@link https://github.com/manzt/manzt/blob/4b04f2/utils/rethrow-unless.js}
*/
// biome-ignore lint/suspicious/noExplicitAny: Ok to use any for generic constraint
export function rethrowUnless<E extends ReadonlyArray<new (...args: any[]) => Error>>(
error: unknown,
...ErrorClasses: E
// biome-ignore lint/suspicious/noExplicitAny: Ok to use any for generic constraint
): asserts error is E[number] extends new (...args: any[]) => infer R ? R : never {
if (!ErrorClasses.some((ErrorClass) => error instanceof ErrorClass)) {
throw error;
}
}

0 comments on commit 21641bf

Please sign in to comment.