diff --git a/package-lock.json b/package-lock.json index 67a1fdb..526db32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "zarr", - "version": "0.4.1", + "version": "0.4.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index cc897d5..7fed878 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zarr", - "version": "0.4.1", + "version": "0.4.2", "description": "Javascript implementation of Zarr", "keywords": [ "ndarray", diff --git a/src/core/index.ts b/src/core/index.ts index ecac027..4cabedc 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -11,7 +11,7 @@ import { BasicIndexer, isContiguousSelection, normalizeIntegerSelection } from ' import { NestedArray } from "../nestedArray"; import { RawArray } from "../rawArray"; import { TypedArray, DTYPE_TYPEDARRAY_MAPPING } from '../nestedArray/types'; -import { ValueError, PermissionError, KeyError, BoundsCheckError, ContainsGroupError } from '../errors'; +import { ValueError, PermissionError, BoundsCheckError, ContainsGroupError, isKeyError } from '../errors'; import { getCodec } from "../compression/registry"; @@ -35,7 +35,7 @@ export interface SetOptions { } export interface GetRawChunkOptions { - storeOptions: O, + storeOptions: O; } export class ZarrArray { @@ -419,7 +419,7 @@ export class ZarrArray { } } catch (error) { - if (error instanceof KeyError) { + if (isKeyError(error)) { // fill with scalar if cKey doesn't exist in store if (this.fillValue !== null) { out.set(outSelection, this.fillValue); @@ -448,7 +448,7 @@ export class ZarrArray { } } const cKey = this.chunkKey(chunkCoords); - const cdata = this.chunkStore.getItem(cKey, opts?.storeOptions) + const cdata = this.chunkStore.getItem(cKey, opts?.storeOptions); const buffer = await this.decodeChunk(await cdata); const outShape = this.chunks.filter(d => d !== 1); // squeeze chunk dim if 1 return new RawArray(buffer, outShape, this.dtype); @@ -502,7 +502,7 @@ export class ZarrArray { const cdata = await this.chunkStore.getItem(cKey); return new RawArray(await this.decodeChunk(cdata), outShape, this.dtype); } catch (error) { - if (error instanceof KeyError) { + if (isKeyError(error)) { // fill with scalar if item doesn't exist const data = new DTYPE_TYPEDARRAY_MAPPING[this.dtype](outSize); return new RawArray(data.fill(this.fillValue as number), outShape); @@ -648,14 +648,13 @@ export class ZarrArray { const dBytes = await this.decodeChunk(chunkStoreData); chunkData = this.toTypedArray(dBytes); } catch (error) { - if (error instanceof KeyError) { + if (isKeyError(error)) { // Chunk is not initialized chunkData = new dtypeConstr(chunkSize); if (this.fillValue !== null) { chunkData.fill(this.fillValue); } - } - else { + } else { // Different type of error - rethrow throw error; } diff --git a/src/errors.ts b/src/errors.ts index bcf40c4..db509a7 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,94 +1,118 @@ +export interface ZarrError { + __zarr__: string; +} + +function isZarrError(err: unknown): err is ZarrError { + return typeof err === 'object' && err !== null && '__zarr__' in err; +} + +export function isKeyError(o: unknown) { + return isZarrError(o) && o.__zarr__ === 'KeyError'; +} + // Custom error messages, note we have to patch the prototype of the // errors to fix `instanceof` calls, see: // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work - -export class ContainsArrayError extends Error { +export class ContainsArrayError extends Error implements ZarrError { + __zarr__ = 'ContainsArrayError'; constructor(path: string) { super(`path ${path} contains an array`); Object.setPrototypeOf(this, ContainsArrayError.prototype); } } -export class ContainsGroupError extends Error { +export class ContainsGroupError extends Error implements ZarrError { + __zarr__ = 'ContainsGroupError'; constructor(path: string) { super(`path ${path} contains a group`); Object.setPrototypeOf(this, ContainsGroupError.prototype); } } -export class ArrayNotFoundError extends Error { +export class ArrayNotFoundError extends Error implements ZarrError { + __zarr__ = 'ArrayNotFoundError'; constructor(path: string) { super(`array not found at path ${path}`); Object.setPrototypeOf(this, ArrayNotFoundError.prototype); } } -export class GroupNotFoundError extends Error { +export class GroupNotFoundError extends Error implements ZarrError { + __zarr__ = 'GroupNotFoundError'; constructor(path: string) { super(`ground not found at path ${path}`); Object.setPrototypeOf(this, GroupNotFoundError.prototype); } } -export class PathNotFoundError extends Error { +export class PathNotFoundError extends Error implements ZarrError { + __zarr__ = 'PathNotFoundError'; constructor(path: string) { super(`nothing not found at path ${path}`); Object.setPrototypeOf(this, PathNotFoundError.prototype); } } -export class PermissionError extends Error { +export class PermissionError extends Error implements ZarrError { + __zarr__ = 'PermissionError'; constructor(message: string) { super(message); Object.setPrototypeOf(this, PermissionError.prototype); } } -export class KeyError extends Error { +export class KeyError extends Error implements ZarrError { + __zarr__ = 'KeyError'; constructor(key: string) { super(`key ${key} not present`); Object.setPrototypeOf(this, KeyError.prototype); } } -export class TooManyIndicesError extends RangeError { +export class TooManyIndicesError extends RangeError implements ZarrError { + __zarr__ = 'TooManyIndicesError'; constructor(selection: any[], shape: number[]) { super(`too many indices for array; expected ${shape.length}, got ${selection.length}`); Object.setPrototypeOf(this, TooManyIndicesError.prototype); } } -export class BoundsCheckError extends RangeError { +export class BoundsCheckError extends RangeError implements ZarrError { + __zarr__ = 'BoundsCheckError'; constructor(message: string) { super(message); Object.setPrototypeOf(this, BoundsCheckError.prototype); } } -export class InvalidSliceError extends RangeError { +export class InvalidSliceError extends RangeError implements ZarrError { + __zarr__ = 'InvalidSliceError'; constructor(from: any, to: any, stepSize: any, reason: any) { super(`slice arguments slice(${from}, ${to}, ${stepSize}) invalid: ${reason}`); Object.setPrototypeOf(this, InvalidSliceError.prototype); } } -export class NegativeStepError extends Error { +export class NegativeStepError extends Error implements ZarrError { + __zarr__ = 'NegativeStepError'; constructor() { super(`Negative step size is not supported when indexing.`); Object.setPrototypeOf(this, NegativeStepError.prototype); } } -export class ValueError extends Error { +export class ValueError extends Error implements ZarrError { + __zarr__ = 'ValueError'; constructor(message: string) { super(message); Object.setPrototypeOf(this, ValueError.prototype); } } -export class HTTPError extends Error { +export class HTTPError extends Error implements ZarrError { + __zarr__ = 'HTTPError'; constructor(code: string) { - super(code); - Object.setPrototypeOf(this, HTTPError.prototype); + super(code); + Object.setPrototypeOf(this, HTTPError.prototype); } - } +}