Skip to content

Commit fd8e352

Browse files
feat: expose raw response in errors
1 parent 885b693 commit fd8e352

File tree

6 files changed

+28
-11
lines changed

6 files changed

+28
-11
lines changed

readme.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ client
114114
if (isVisitorsError(err)) {
115115
if (err.code === 429) {
116116
// VisitorsError429 type
117+
118+
// You can also access raw response
119+
console.log(err.response);
120+
117121
retryLater(err.retryAfter); // this function needs to be implemented on your side
118122
} else {
119123
console.log('error: ', err.error);
@@ -128,6 +132,9 @@ client
128132
.then((result) => console.log(result))
129133
.catch((err) => {
130134
if (isEventError(err)) {
135+
// You can also access raw response
136+
console.log(err.response);
137+
131138
console.log(`error ${err.code}: `, err.error.message);
132139
} else {
133140
console.log('unknown error: ', err);

src/serverApiClient.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export class FingerprintJsServerApiClient {
6363
.then(async (response) => {
6464
const jsonResponse = await response.json()
6565
if (response.status !== 200) {
66-
throw { ...(jsonResponse as EventError), status: response.status } as EventError
66+
throw { ...(jsonResponse as EventError), response, status: response.status } as EventError
6767
}
6868
return jsonResponse as EventResponse
6969
})
@@ -72,6 +72,7 @@ export class FingerprintJsServerApiClient {
7272
throw err
7373
}
7474
const error = (err as unknown) instanceof Error ? (err as Error).toString() : JSON.stringify(err)
75+
7576
throw {
7677
status: 0,
7778
error: error,
@@ -110,7 +111,7 @@ export class FingerprintJsServerApiClient {
110111

111112
const jsonResponse = await response.json()
112113

113-
throw { ...(jsonResponse as DeleteVisitorError), status: response.status } as DeleteVisitorError
114+
throw { ...(jsonResponse as DeleteVisitorError), response, status: response.status } as DeleteVisitorError
114115
})
115116
.catch((err) => {
116117
if (isDeleteVisitorError(err)) {
@@ -153,7 +154,7 @@ export class FingerprintJsServerApiClient {
153154
const retryAfter = response.headers.get('retry-after') || ''
154155
;(jsonResponse as VisitorsError429).retryAfter = retryAfter === '' ? 1 : parseInt(retryAfter)
155156
}
156-
throw { ...(jsonResponse as VisitorsError), status: response.status } as VisitorsError
157+
throw { ...(jsonResponse as VisitorsError), response, status: response.status } as VisitorsError
157158
})
158159
.catch((err: Error) => {
159160
if (isVisitorsError(err)) {

src/types.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ export type DeleteVisitError403 =
6464
status: 403
6565
}
6666

67-
export type VisitorsError = VisitorsError403 | VisitorsError429
67+
export type VisitorsError = WithResponse<VisitorsError403 | VisitorsError429>
6868

69-
export type DeleteVisitorError = DeleteVisitError404 | DeleteVisitError403
69+
export type DeleteVisitorError = WithResponse<DeleteVisitError404 | DeleteVisitError403>
7070

7171
export function isVisitorsError(response: any): response is EventError {
7272
return (
@@ -94,14 +94,19 @@ export type EventResponse = paths['/events/{request_id}']['get']['responses']['2
9494
export type EventError403 = paths['/events/{request_id}']['get']['responses']['403']['content']['application/json']
9595
export type EventError404 = paths['/events/{request_id}']['get']['responses']['404']['content']['application/json']
9696

97-
type GenericEventError = EventError403 | EventError404
97+
type WithResponse<T> = T & {
98+
response: Response
99+
}
98100

99-
type EventErrorCode<T extends GenericEventError> = T extends EventError403 ? 403 : 404
101+
type GenericEventError = WithResponse<EventError403 | EventError404>
100102

101-
export type EventError<T extends GenericEventError = GenericEventError> = T & {
102-
status: EventErrorCode<T>
103-
}
103+
type EventErrorCode<T extends GenericEventError> = T extends EventError403 ? 403 : 404
104104

105+
export type EventError<T extends GenericEventError = GenericEventError> = WithResponse<
106+
T & {
107+
status: EventErrorCode<T>
108+
}
109+
>
105110
export function isEventError(response: any): response is EventError {
106111
return (
107112
(response?.hasOwnProperty('status') &&

tests/mocked-responses-tests/__snapshots__/castVisitorWebhookTest.spec.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ exports[`[Mocked body] Cast visitor webhook with sample request body 1`] = `
184184
"vpn": {
185185
"methods": {
186186
"auxiliaryMobile": false,
187+
"osMismatch": false,
187188
"publicVPN": false,
188189
"timezoneMismatch": false,
189190
},

tests/mocked-responses-tests/__snapshots__/getEventTests.spec.ts.snap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
exports[`[Mocked response] Get Event Error with bad shape 1`] = `
44
{
5-
"error": "{"error":"Some text instead og shaped object","status":404}",
5+
"error": "{"error":"Some text instead og shaped object","response":{},"status":404}",
66
"status": 0,
77
}
88
`;
@@ -34,6 +34,7 @@ exports[`[Mocked response] Get Event with additional signals 1`] = `
3434
"userAgent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) ....",
3535
},
3636
"confidence": {
37+
"revision": "v1.1",
3738
"score": 0.97,
3839
},
3940
"firstSeenAt": {
@@ -514,6 +515,7 @@ exports[`[Mocked response] Get Event with request_id 1`] = `
514515
"data": {
515516
"methods": {
516517
"auxiliaryMobile": false,
518+
"osMismatch": false,
517519
"publicVPN": false,
518520
"timezoneMismatch": false,
519521
},

tests/mocked-responses-tests/deleteVisitorDataTests.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ describe('[Mocked response] Delete visitor data', () => {
8181
await expect(client.deleteVisitorData(existingVisitorId)).rejects.toEqual({
8282
status: 0,
8383
error: {
84+
response: expect.any(Response),
8485
error: errorInfo,
8586
status: 404,
8687
},

0 commit comments

Comments
 (0)