Skip to content

Commit

Permalink
Inline error handling logic in provides
Browse files Browse the repository at this point in the history
  • Loading branch information
axelboc committed Aug 21, 2024
1 parent 1c43be2 commit 47a4e9c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 73 deletions.
50 changes: 39 additions & 11 deletions packages/app/src/providers/h5grove/h5grove-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import type {
import { DTypeClass } from '@h5web/shared/hdf5-models';
import type { OnProgress } from '@h5web/shared/react-suspense-fetch';
import type { AxiosInstance, AxiosRequestConfig } from 'axios';
import axios from 'axios';
import axios, { AxiosError } from 'axios';

import { DataProviderApi } from '../api';
import type { ExportFormat, ExportURL, ValuesStoreParams } from '../models';
import { createAxiosProgressHandler, processAxiosError } from '../utils';
import { createAxiosProgressHandler } from '../utils';
import type {
H5GroveAttrValuesResponse,
H5GroveDataResponse,
Expand All @@ -23,8 +23,8 @@ import type {
} from './models';
import {
h5groveTypedArrayFromDType,
isH5GroveError,
parseEntity,
processFetchEntityError,
} from './utils';

export class H5GroveApi extends DataProviderApi {
Expand Down Expand Up @@ -79,14 +79,16 @@ export class H5GroveApi extends DataProviderApi {

return await this.fetchData(params, signal, onProgress);
} catch (error) {
throw processAxiosError(error, (axiosError) => {
return (
axios.isCancel(axiosError) &&
// Throw abort reason instead of axios `CancelError`
// https://github.com/axios/axios/issues/5758
(typeof signal?.reason === 'string' ? signal.reason : 'cancelled')
if (error instanceof AxiosError && axios.isCancel(error)) {
// Throw abort reason instead of axios `CancelError`
// https://github.com/axios/axios/issues/5758
throw new Error(
typeof signal?.reason === 'string' ? signal.reason : 'cancelled',
{ cause: error },
);
});
}

throw error;
}
}

Expand Down Expand Up @@ -140,7 +142,33 @@ export class H5GroveApi extends DataProviderApi {
});
return data;
} catch (error) {
throw processFetchEntityError(error, path, this.filepath);
if (
!(error instanceof AxiosError) ||
!isH5GroveError(error.response?.data)
) {
throw error;
}

const { message } = error.response.data;
if (message.includes('File not found')) {
throw new Error(`File not found: '${this.filepath}'`, { cause: error });
}
if (message.includes('Permission denied')) {
throw new Error(
`Cannot read file '${this.filepath}': Permission denied`,
{ cause: error },
);
}
if (message.includes('not a valid path')) {
throw new Error(`No entity found at ${path}`, { cause: error });
}
if (message.includes('Cannot resolve')) {
throw new Error(`Could not resolve soft link at ${path}`, {
cause: error,
});
}

throw error;
}
}

Expand Down
39 changes: 4 additions & 35 deletions packages/app/src/providers/h5grove/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from '@h5web/shared/hdf5-utils';
import type { TypedArrayConstructor } from '@h5web/shared/vis-models';

import { processAxiosError, typedArrayFromDType } from '../utils';
import { typedArrayFromDType } from '../utils';
import type {
H5GroveAttribute,
H5GroveEntity,
Expand Down Expand Up @@ -134,7 +134,9 @@ function parseAttributes(attrsMetadata: H5GroveAttribute[]): Attribute[] {
}));
}

function isH5GroveError(payload: unknown): payload is H5GroveErrorResponse {
export function isH5GroveError(
payload: unknown,
): payload is H5GroveErrorResponse {
return (
!!payload &&
typeof payload === 'object' &&
Expand All @@ -143,39 +145,6 @@ function isH5GroveError(payload: unknown): payload is H5GroveErrorResponse {
);
}

export function processFetchEntityError(
error: unknown,
entityPath: string,
filePath: string,
): unknown {
return processAxiosError(error, (axiosError) => {
if (!axiosError.response) {
return undefined;
}

const { data } = axiosError.response;
if (!isH5GroveError(data)) {
return undefined;
}

const { message } = data;
if (message.includes('File not found')) {
return `File not found: '${filePath}'`;
}
if (message.includes('Permission denied')) {
return `Cannot read file '${filePath}': Permission denied`;
}
if (message.includes('not a valid path')) {
return `No entity found at ${entityPath}`;
}
if (message.includes('Cannot resolve')) {
return `Could not resolve soft link at ${entityPath}`;
}

return undefined;
});
}

export function parseDType(type: H5GroveType): DType {
const { class: h5tClass, size } = type;

Expand Down
29 changes: 17 additions & 12 deletions packages/app/src/providers/hsds/hsds-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import { EntityKind } from '@h5web/shared/hdf5-models';
import { buildEntityPath, getChildEntity } from '@h5web/shared/hdf5-utils';
import type { OnProgress } from '@h5web/shared/react-suspense-fetch';
import type { AxiosInstance } from 'axios';
import axios from 'axios';
import axios, { AxiosError } from 'axios';

import { DataProviderApi } from '../api';
import type { ExportFormat, ExportURL, ValuesStoreParams } from '../models';
import { createAxiosProgressHandler, processAxiosError } from '../utils';
import { createAxiosProgressHandler } from '../utils';
import type {
BaseHsdsEntity,
HsdsAttribute,
Expand Down Expand Up @@ -180,9 +180,11 @@ export class HsdsApi extends DataProviderApi {
const { data } = await this.client.get<HsdsRootResponse>('/');
return data.root;
} catch (error) {
throw processAxiosError(error, (axiosError) => {
return axiosError.status === 400 && `File not found: ${this.filepath}`;
});
if (error instanceof AxiosError && error.status === 400) {
throw new Error(`File not found: ${this.filepath}`, { cause: error });
}

throw error;
}
}

Expand Down Expand Up @@ -236,16 +238,19 @@ export class HsdsApi extends DataProviderApi {
signal,
onDownloadProgress: createAxiosProgressHandler(onProgress),
});

return data.value;
} catch (error) {
throw processAxiosError(error, (axiosError) => {
return (
axios.isCancel(axiosError) &&
// Throw abort reason instead of axios `CancelError`
// https://github.com/axios/axios/issues/5758
(typeof signal?.reason === 'string' ? signal.reason : 'cancelled')
if (error instanceof AxiosError && axios.isCancel(error)) {
// Throw abort reason instead of axios `CancelError`
// https://github.com/axios/axios/issues/5758
throw new Error(
typeof signal?.reason === 'string' ? signal.reason : 'cancelled',
{ cause: error },
);
});
}

throw error;
}
}

Expand Down
15 changes: 0 additions & 15 deletions packages/app/src/providers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type {
import { DTypeClass } from '@h5web/shared/hdf5-models';
import type { OnProgress } from '@h5web/shared/react-suspense-fetch';
import type { AxiosProgressEvent } from 'axios';
import { AxiosError } from 'axios';

import type { DataProviderApi } from './api';

Expand Down Expand Up @@ -77,20 +76,6 @@ export async function getValueOrError(
}
}

export function processAxiosError(
error: unknown,
getMessageToThrow: (error: AxiosError) => string | false | undefined,
): unknown {
if (error instanceof AxiosError) {
const messageToThrow = getMessageToThrow(error);
if (messageToThrow) {
return new Error(messageToThrow, { cause: error });
}
}

return error;
}

export function createAxiosProgressHandler(onProgress: OnProgress | undefined) {
return (
onProgress &&
Expand Down

0 comments on commit 47a4e9c

Please sign in to comment.