Skip to content

Commit

Permalink
refactor error types
Browse files Browse the repository at this point in the history
  • Loading branch information
andykswong committed Oct 16, 2023
1 parent a655cfa commit 27d5c15
Show file tree
Hide file tree
Showing 42 changed files with 666 additions and 536 deletions.
50 changes: 37 additions & 13 deletions packages/collections/src/batch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AbortOptions, CodedError, ErrorCode, operationError } from '@mithic/commons';
import { AbortOptions, CodedError, OperationError } from '@mithic/commons';
import {
MaybeAsyncAppendOnlySet, MaybeAsyncReadonlySet, MaybeAsyncReadonlySetBatch, MaybeAsyncSet, MaybeAsyncSetAddBatch,
MaybeAsyncSetDeleteBatch, MaybeAsyncSetUpdateBatch
Expand Down Expand Up @@ -48,8 +48,12 @@ export async function* deleteMany<K>(
try {
await data.delete(key, options);
yield;
} catch (error) {
yield operationError('Failed to delete key', (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error);
} catch (cause) {
yield new OperationError('failed to delete key', {
cause,
code: (cause as CodedError)?.code,
detail: key,
});
}
}
}
Expand All @@ -67,8 +71,12 @@ export async function* addMany<K>(
try {
await data.add(key, options);
yield;
} catch (error) {
yield operationError('Failed to add key', (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error);
} catch (cause) {
yield new OperationError('failed to add key', {
cause,
code: (cause as CodedError)?.code,
detail: key,
});
}
}
}
Expand All @@ -86,8 +94,12 @@ export async function* setMany<K, V>(
try {
await data.set(key, value, options);
yield;
} catch (error) {
yield operationError('Failed to set key', (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error);
} catch (cause) {
yield new OperationError('failed to set key', {
cause,
code: (cause as CodedError)?.code,
detail: key,
});
}
}
}
Expand All @@ -107,8 +119,12 @@ export async function* updateSetMany<K>(
try {
await (isDelete ? data.delete(key, options) : data.add(key, options));
yield;
} catch (error) {
yield operationError(`Failed to update key`, (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error);
} catch (cause) {
yield new OperationError(`failed to update key`, {
cause,
code: (cause as CodedError)?.code,
detail: key,
});
}
}
}
Expand All @@ -127,8 +143,12 @@ export async function* updateMapMany<K, V>(
try {
await ((value !== void 0) ? data.set(key, value, options) : data.delete(key, options));
yield;
} catch (error) {
yield operationError('Failed to update key', (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error);
} catch (cause) {
yield new OperationError('failed to update key', {
cause,
code: (cause as CodedError)?.code,
detail: key,
});
}
}
}
Expand All @@ -145,11 +165,15 @@ export async function* putMany<K, V>(
options?.signal?.throwIfAborted();
try {
yield [await data.put(value, options)];
} catch (error) {
} catch (cause) {
const key = await data.getKey(value, options);
yield [
key,
operationError('Failed to put key', (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error)
new OperationError('failed to put key', {
cause,
code: (cause as CodedError)?.code,
detail: key,
})
];
}
}
Expand Down
14 changes: 7 additions & 7 deletions packages/collections/src/impl/__tests__/batchmap.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
import { ErrorCode, operationError } from '@mithic/commons';
import { SyncMapBatchAdapter } from '../batchmap.js';
import { OperationError } from '@mithic/commons';

const DATA = [[1, 'value1'], [2, 'value2'], [3, 'value3']] as const;

Expand Down Expand Up @@ -43,7 +43,7 @@ describe(SyncMapBatchAdapter.name, () => {

it('should handle errors while setting many values synchronously in the map', () => {
const entries = [[1, 'x'], [2, 'y'], [3, 'z']] as [number, string][];
const error = new Error('Failed');
const error = new Error('failed');
adapter.set = jest.fn(key => {
if (key === 2) {
throw error;
Expand All @@ -52,7 +52,7 @@ describe(SyncMapBatchAdapter.name, () => {
const errors = [...adapter.setMany(entries)];
expect(errors).toEqual([
void 0,
operationError('Failed to set value', ErrorCode.OpFailed, 2, error),
new OperationError('failed to set value', { detail: 2, cause: error }),
void 0
]);
});
Expand All @@ -68,7 +68,7 @@ describe(SyncMapBatchAdapter.name, () => {

it('should handle errors while deleting many values synchronously from the map', () => {
const keys = [1, 2, 3];
const error = new Error('Failed');
const error = new Error('failed');
adapter.delete = jest.fn(key => {
if (key === 3) {
throw error;
Expand All @@ -77,7 +77,7 @@ describe(SyncMapBatchAdapter.name, () => {
const errors = [...adapter.deleteMany(keys)];
expect(errors).toEqual([
void 0, void 0,
operationError('Failed to delete key', ErrorCode.OpFailed, 3, error),
new OperationError('failed to delete key', { detail: 3, cause: error }),
]);
});
});
Expand All @@ -95,7 +95,7 @@ describe(SyncMapBatchAdapter.name, () => {

it('should handle errors while setting many values synchronously in the map', () => {
const entries = [[1, 'x'], [2], [3, 'z']] as [number, string | undefined][];
const error = new Error('Failed');
const error = new Error('failed');
adapter.set = jest.fn(key => {
if (key === 3) {
throw error;
Expand All @@ -105,7 +105,7 @@ describe(SyncMapBatchAdapter.name, () => {
expect(errors).toEqual([
void 0,
void 0,
operationError('Failed to update key', ErrorCode.OpFailed, 3, error),
new OperationError('failed to update key', { detail: 3, cause: error }),
]);
});
});
Expand Down
25 changes: 14 additions & 11 deletions packages/collections/src/impl/__tests__/encodedmap.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
import { ErrorCode, operationError } from '@mithic/commons';
import { OperationError } from '@mithic/commons';
import { MaybeAsyncMap } from '../../map.js';
import { EncodedMap } from '../encodedmap.js';

Expand Down Expand Up @@ -90,15 +90,16 @@ describe.each([
it('should return errors from underlying map', async () => {
if ('setMany' in map.map) return; // skip test

jest.spyOn(map.map, 'set').mockImplementation(() => { throw new Error('error'); });
const cause = new Error('error');
jest.spyOn(map.map, 'set').mockImplementation(() => { throw cause; });

const results = [];
for await (const error of map.setMany([[K1, 1], [K3, 3]])) {
results.push(error);
}
expect(results).toEqual([
operationError(`Failed to set key`, ErrorCode.OpFailed, K1, new Error('error')),
operationError(`Failed to set key`, ErrorCode.OpFailed, K3, new Error('error')),
new OperationError(`failed to set key`, { detail: K1, cause }),
new OperationError(`failed to set key`, { detail: K3, cause }),
])
});
});
Expand All @@ -115,15 +116,16 @@ describe.each([
it('should return errors from underlying map', async () => {
if ('deleteMany' in map.map) return; // skip test

jest.spyOn(map.map, 'delete').mockImplementation(() => { throw new Error('error'); });
const cause = new Error('error');
jest.spyOn(map.map, 'delete').mockImplementation(() => { throw cause; });

const results = [];
for await (const error of map.deleteMany([K1, K2])) {
results.push(error);
}
expect(results).toEqual([
operationError(`Failed to delete key`, ErrorCode.OpFailed, K1, new Error('error')),
operationError(`Failed to delete key`, ErrorCode.OpFailed, K2, new Error('error')),
new OperationError(`failed to delete key`, { detail: K1, cause }),
new OperationError(`failed to delete key`, { detail: K2, cause }),
])
});
});
Expand All @@ -143,16 +145,17 @@ describe.each([
it('should return errors from underlying map', async () => {
if ('updateMany' in map.map) return; // skip test

jest.spyOn(map.map, 'set').mockImplementation(() => { throw new Error('error'); });
jest.spyOn(map.map, 'delete').mockImplementation(() => { throw new Error('error'); });
const cause = new Error('error');
jest.spyOn(map.map, 'set').mockImplementation(() => { throw cause; });
jest.spyOn(map.map, 'delete').mockImplementation(() => { throw cause; });

const results = [];
for await (const error of map.updateMany([[K1, 123], [K2, void 0]])) {
results.push(error);
}
expect(results).toEqual([
operationError(`Failed to update key`, ErrorCode.OpFailed, K1, new Error('error')),
operationError(`Failed to update key`, ErrorCode.OpFailed, K2, new Error('error')),
new OperationError(`failed to update key`, { detail: K1, cause }),
new OperationError(`failed to update key`, { detail: K2, cause }),
])
});
});
Expand Down
25 changes: 14 additions & 11 deletions packages/collections/src/impl/__tests__/encodedset.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
import { ErrorCode, operationError } from '@mithic/commons';
import { OperationError } from '@mithic/commons';
import { MaybeAsyncSet } from '../../set.js';
import { EncodedSet } from '../encodedset.js';

Expand Down Expand Up @@ -79,15 +79,16 @@ describe.each([
it('should return errors from underlying set', async () => {
if ('addMany' in set.set) return; // skip test

jest.spyOn(set.set, 'add').mockImplementation(() => { throw new Error('error'); });
const cause = new Error('error')
jest.spyOn(set.set, 'add').mockImplementation(() => { throw cause; });

const results = [];
for await (const error of set.addMany([K1, K2])) {
results.push(error);
}
expect(results).toEqual([
operationError(`Failed to add key`, ErrorCode.OpFailed, K1, new Error('error')),
operationError(`Failed to add key`, ErrorCode.OpFailed, K2, new Error('error')),
new OperationError(`failed to add key`, { detail: K1, cause }),
new OperationError(`failed to add key`, { detail: K2, cause }),
])
});
});
Expand All @@ -104,15 +105,16 @@ describe.each([
it('should return errors from underlying set', async () => {
if ('deleteMany' in set.set) return; // skip test

jest.spyOn(set.set, 'delete').mockImplementation(() => { throw new Error('error'); });
const cause = new Error('error')
jest.spyOn(set.set, 'delete').mockImplementation(() => { throw cause; });

const results = [];
for await (const error of set.deleteMany([K1, K2])) {
results.push(error);
}
expect(results).toEqual([
operationError(`Failed to delete key`, ErrorCode.OpFailed, K1, new Error('error')),
operationError(`Failed to delete key`, ErrorCode.OpFailed, K2, new Error('error')),
new OperationError(`failed to delete key`, { detail: K1, cause }),
new OperationError(`failed to delete key`, { detail: K2, cause }),
])
});
});
Expand All @@ -129,16 +131,17 @@ describe.each([
it('should return errors from underlying set', async () => {
if ('addMany' in set.set) return; // skip test

jest.spyOn(set.set, 'add').mockImplementation(() => { throw new Error('error'); });
jest.spyOn(set.set, 'delete').mockImplementation(() => { throw new Error('error'); });
const cause = new Error('error')
jest.spyOn(set.set, 'add').mockImplementation(() => { throw cause; });
jest.spyOn(set.set, 'delete').mockImplementation(() => { throw cause; });

const results = [];
for await (const error of set.updateMany([[K1, true], [K3]])) {
results.push(error);
}
expect(results).toEqual([
operationError(`Failed to update key`, ErrorCode.OpFailed, K1, new Error('error')),
operationError(`Failed to update key`, ErrorCode.OpFailed, K3, new Error('error')),
new OperationError(`failed to update key`, { detail: K1, cause }),
new OperationError(`failed to update key`, { detail: K3, cause }),
])
});
});
Expand Down
26 changes: 19 additions & 7 deletions packages/collections/src/impl/batchmap.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AbortOptions, CodedError, ErrorCode, operationError } from '@mithic/commons';
import { AbortOptions, CodedError, OperationError } from '@mithic/commons';
import { MaybeAsyncMap, MaybeAsyncMapBatch } from '../map.js';

/** Abstract base class to provide default synchronous batch API implementations for a {@link MaybeAsyncMap}. */
Expand Down Expand Up @@ -28,8 +28,12 @@ export abstract class SyncMapBatchAdapter<K, V> implements MaybeAsyncMap<K, V>,
try {
this.set(key, value, options);
yield;
} catch (error) {
yield operationError('Failed to set value', (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error);
} catch (cause) {
yield new OperationError('failed to set value', {
cause,
code: (cause as CodedError)?.code,
detail: key
});
}
}
}
Expand All @@ -40,8 +44,12 @@ export abstract class SyncMapBatchAdapter<K, V> implements MaybeAsyncMap<K, V>,
try {
this.delete(key, options);
yield;
} catch (error) {
yield operationError('Failed to delete key', (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error);
} catch (cause) {
yield new OperationError('failed to delete key', {
cause,
code: (cause as CodedError)?.code,
detail: key
});
}
}
}
Expand All @@ -52,8 +60,12 @@ export abstract class SyncMapBatchAdapter<K, V> implements MaybeAsyncMap<K, V>,
try {
(value !== void 0) ? this.set(key, value, options) : this.delete(key, options);
yield;
} catch (error) {
yield operationError('Failed to update key', (error as CodedError)?.code ?? ErrorCode.OpFailed, key, error);
} catch (cause) {
yield new OperationError('failed to update key', {
cause,
code: (cause as CodedError)?.code,
detail: key
});
}
}
}
Expand Down
13 changes: 6 additions & 7 deletions packages/collections/src/impl/camap.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
AbortOptions, CodedError, ContentId, ErrorCode, MaybePromise, maybeAsync, operationError, sha256
AbortOptions, CodedError, ContentId, MaybePromise, OperationError, maybeAsync, sha256
} from '@mithic/commons';
import { CID } from 'multiformats';
import * as raw from 'multiformats/codecs/raw';
Expand Down Expand Up @@ -71,12 +71,11 @@ export class ContentAddressedMapStore<
const key = entries[i++][0];
yield [
key,
error && operationError(
'Failed to put',
(error as CodedError)?.code ?? ErrorCode.OpFailed,
key,
error
)
error && new OperationError('failed to put', {
code: (error as CodedError)?.code,
detail: key,
cause: error
})
];
}
}
Expand Down
Loading

0 comments on commit 27d5c15

Please sign in to comment.