Skip to content

Commit 41dc8a0

Browse files
authored
feat: add gaxios error handler (VF-000) (#88)
* feat: add gaxios error handler (VF-000) * fix: add error logs * chore: pin gaxios version * refactor: expose type guards
1 parent 7c8e15d commit 41dc8a0

File tree

13 files changed

+151
-24
lines changed

13 files changed

+151
-24
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@voiceflow/verror": "^1.1.0",
1717
"chai": "^4.3.4",
1818
"dotenv": "^10.0.0",
19+
"gaxios": "4.3.2",
1920
"http-errors": "^2.0.0",
2021
"http-status": "^1.4.2",
2122
"jszip": "3.7.1",

src/guards/error.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import VError from '@voiceflow/verror';
2+
import { GaxiosError } from 'gaxios';
3+
import { isHttpError } from 'http-errors';
4+
import { types } from 'util';
5+
6+
export const isJavascriptError = types.isNativeError;
7+
8+
export const isGaxiosError = (err: unknown): err is GaxiosError => err instanceof GaxiosError;
9+
10+
export const isVError = (err: unknown): err is VError => err != null && err instanceof VError;
11+
12+
export { isHttpError };

src/guards/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './error';

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './clients';
22
export * as Common from './common';
33
export * from './env';
44
export { default as FixtureGenerator } from './fixtureGenerator';
5+
export * as Guards from './guards';
56
export * from './middlewares';
67
export { default as ResponseBuilder } from './responseBuilder';
78
export * from './types';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { GaxiosError } from 'gaxios';
2+
3+
import type { ExceptionFormatter } from '../types';
4+
5+
export const formatGaxiosError: ExceptionFormatter<GaxiosError> = (err) => {
6+
return {
7+
statusCode: err.response?.status,
8+
name: 'GaxiosError',
9+
message: err.message,
10+
details: {
11+
code: err.code,
12+
statusText: err.response?.statusText,
13+
},
14+
};
15+
};

src/middlewares/exception/formatters/httpError.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import { HttpError, isHttpError } from 'http-errors';
1+
import { HttpError } from 'http-errors';
22

33
import type { ExceptionFormatter } from '../types';
44

5-
export { isHttpError };
6-
75
export const formatHttpError: ExceptionFormatter<HttpError> = (err) => {
86
return {
97
statusCode: err.statusCode,

src/middlewares/exception/formatters/index.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import VError from '@voiceflow/verror';
22

3+
import * as Guards from '../../../guards';
34
import type { ExceptionFormat } from '../types';
4-
import { formatHttpError, isHttpError } from './httpError';
5-
import { formatJavascriptError, isJavascriptError } from './jsError';
6-
import { formatVError, isVError } from './vError';
5+
import { formatGaxiosError } from './gaxiosError';
6+
import { formatHttpError } from './httpError';
7+
import { formatJavascriptError } from './jsError';
8+
import { formatVError } from './vError';
79

810
export const formatError = (err: unknown): ExceptionFormat => {
911
let exception: ExceptionFormat = {
@@ -12,9 +14,10 @@ export const formatError = (err: unknown): ExceptionFormat => {
1214
message: 'Unknown error',
1315
};
1416

15-
if (isVError(err)) exception = mergeExceptionResult(exception, formatVError(err));
16-
else if (isHttpError(err)) exception = mergeExceptionResult(exception, formatHttpError(err));
17-
else if (isJavascriptError(err)) exception = mergeExceptionResult(exception, formatJavascriptError(err));
17+
if (Guards.isVError(err)) exception = mergeExceptionResult(exception, formatVError(err));
18+
else if (Guards.isHttpError(err)) exception = mergeExceptionResult(exception, formatHttpError(err));
19+
else if (Guards.isGaxiosError(err)) exception = mergeExceptionResult(exception, formatGaxiosError(err));
20+
else if (Guards.isJavascriptError(err)) exception = mergeExceptionResult(exception, formatJavascriptError(err));
1821

1922
return exception;
2023
};

src/middlewares/exception/formatters/jsError.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
import { types } from 'util';
2-
31
import type { ExceptionFormatter } from '../types';
42

5-
export const isJavascriptError = types.isNativeError;
6-
73
export const formatJavascriptError: ExceptionFormatter<Error> = (err) => {
84
return {
95
name: err.name,

src/middlewares/exception/formatters/vError.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import VError from '@voiceflow/verror';
22

33
import type { ExceptionFormatter } from '../types';
44

5-
export const isVError = (err: unknown): err is VError => err != null && err instanceof VError;
6-
75
export const formatVError: ExceptionFormatter<VError> = (err) => {
86
return {
97
statusCode: err.code,

src/middlewares/exception/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { NextFunction, Request, Response } from 'express';
22

3+
import log from '../../logger';
34
import { AbstractMiddleware } from '../../types';
45
import { formatError } from './formatters';
56

@@ -9,11 +10,17 @@ export class ExceptionMiddleware extends AbstractMiddleware<never, never> {
910
}
1011

1112
public handleError(err: unknown, req: Request, res: Response, _next: NextFunction): void {
13+
log.error(`Exception formatter (pre) ${JSON.stringify(err)}`);
14+
1215
const { statusCode, ...body } = formatError(err);
1316

14-
res.status(statusCode).send({
17+
const error = {
1518
...body,
1619
requestID: req.id.toString(),
17-
});
20+
};
21+
22+
log.error(`Exception formatter (post) ${JSON.stringify(error)}`);
23+
24+
res.status(statusCode).send(error);
1825
}
1926
}

0 commit comments

Comments
 (0)