Skip to content

Commit

Permalink
Add ZarrError interface to allow custom errors (#79)
Browse files Browse the repository at this point in the history
* Add ZarrError interface to allow custom errors

* Move comment about errors

* 0.4.2
  • Loading branch information
manzt authored Mar 1, 2021
1 parent 59c8b6c commit 0889167
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 27 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zarr",
"version": "0.4.1",
"version": "0.4.2",
"description": "Javascript implementation of Zarr",
"keywords": [
"ndarray",
Expand Down
15 changes: 7 additions & 8 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";


Expand All @@ -35,7 +35,7 @@ export interface SetOptions {
}

export interface GetRawChunkOptions<O> {
storeOptions: O,
storeOptions: O;
}

export class ZarrArray {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
58 changes: 41 additions & 17 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
}

0 comments on commit 0889167

Please sign in to comment.