Skip to content

Commit 28bbc38

Browse files
SK-2119: fix type gaps for error handling (#219)
1 parent cf6200f commit 28bbc38

3 files changed

Lines changed: 195 additions & 67 deletions

File tree

‎src/vault/client/index.ts‎

Lines changed: 148 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { AuthInfo, AuthType, LogLevel, MessageType, printLog, TYPES } from "../.
1010
import { isExpired } from "../../utils/jwt-utils";
1111
import logs from "../../utils/logs";
1212
import Credentials from "../config/credentials";
13+
import { SkyflowApiErrorLegacy, SkyflowApiErrorNewFormat, SkyflowErrorData } from "../types";
1314

1415
class VaultClient {
1516

@@ -127,12 +128,12 @@ class VaultClient {
127128
this.skyflowCredentials = credentials;
128129
}
129130

130-
private normalizeErrorMeta(err: any) {
131-
const isNewFormat = !!err?.rawResponse;
131+
private normalizeErrorMeta(err: SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy | SkyflowError | Error) {
132+
const isNewFormat = (err as SkyflowApiErrorNewFormat).rawResponse !== undefined;
132133
if (isNewFormat) {
133-
const headers = err?.rawResponse?.headers;
134+
const headers = (err as SkyflowApiErrorNewFormat).rawResponse?.headers;
134135
const contentType = headers?.get('content-type');
135-
const requestId = headers?.get('x-request-id');
136+
const requestId = headers?.get('x-request-id') || '';
136137
const errorFromClientHeader = headers?.get('error-from-client');
137138
const errorFromClient = errorFromClientHeader
138139
? String(errorFromClientHeader).toLowerCase() === 'true'
@@ -145,9 +146,9 @@ class VaultClient {
145146
errorFromClient
146147
};
147148
} else {
148-
const headers = err?.headers || {};
149+
const headers = (err as SkyflowApiErrorLegacy).headers || {};
149150
const contentType = headers.get('content-type');
150-
const requestId = headers.get('x-request-id');
151+
const requestId = headers.get('x-request-id') || '';
151152

152153

153154

@@ -166,104 +167,186 @@ class VaultClient {
166167
}
167168

168169

169-
failureResponse = (err: any) => new Promise((_, reject) => {
170+
failureResponse = (err: SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy | SkyflowError | Error) => new Promise((_, reject) => {
170171
const { isNewFormat, contentType, requestId, errorFromClient } = this.normalizeErrorMeta(err);
171172

172-
const data = isNewFormat ? err?.body?.error : err;
173+
const data: SkyflowErrorData = isNewFormat
174+
? (err as SkyflowApiErrorNewFormat).body?.error
175+
: (err as SkyflowApiErrorLegacy).body?.error;
173176

174177
if (contentType) {
175178
if (contentType.includes('application/json')) {
176-
this.handleJsonError(err, data, requestId, reject, errorFromClient);
179+
this.handleJsonError(err as SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy, data, requestId, reject, errorFromClient);
177180
} else if (contentType.includes('text/plain')) {
178-
this.handleTextError(err, data, requestId, reject, errorFromClient);
181+
this.handleTextError(err as SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy, data, requestId, reject, errorFromClient);
179182
} else {
180-
this.handleGenericError(err, requestId, reject, errorFromClient);
183+
this.handleGenericError(err as SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy, requestId, reject, errorFromClient);
181184
}
182185
} else {
183-
this.handleGenericError(err, requestId, reject, errorFromClient);
186+
this.handleGenericError(err as SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy, requestId, reject, errorFromClient);
184187
}
185188
});
186-
187189

188-
private handleJsonError(err: any, data: any, requestId: string, reject: Function, errorFromClient?: boolean) {
189-
const isNewFormat = !!err?.rawResponse;
190-
190+
191+
private isSkyflowApiErrorNewFormat(err: SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy): err is SkyflowApiErrorNewFormat {
192+
return (err as SkyflowApiErrorNewFormat).rawResponse !== undefined;
193+
}
194+
195+
private handleJsonError(
196+
err: SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy,
197+
data: SkyflowErrorData,
198+
requestId: string,
199+
reject: Function,
200+
errorFromClient?: boolean
201+
) {
202+
const isNewFormat = this.isSkyflowApiErrorNewFormat(err);
203+
191204
if (isNewFormat) {
192-
let description = data?.message;
193-
const grpcCode = data?.grpc_code;
194-
const status = data?.http_status;
195-
let details = data?.details || [];
196-
205+
const errorData = data as SkyflowApiErrorNewFormat['body']['error'];
206+
let description: string = errorData?.message;
207+
const grpcCode: number | string | undefined = errorData?.grpc_code;
208+
const status: number | undefined = errorData?.http_code;
209+
let details: any = errorData?.details || [];
210+
197211
if (errorFromClient !== undefined) {
198-
details = Array.isArray(details)
199-
? [...details, { errorFromClient }]
200-
: [{ errorFromClient }];
212+
details = Array.isArray(details)
213+
? [...details, { errorFromClient }]
214+
: [{ errorFromClient }];
201215
}
202-
203-
this.logAndRejectError(description, err, requestId, reject, status, grpcCode, details, isNewFormat);
216+
217+
this.logAndRejectError(
218+
description,
219+
err,
220+
requestId,
221+
reject,
222+
status,
223+
grpcCode,
224+
details,
225+
isNewFormat
226+
);
204227
} else {
205-
let description = data;
206-
const statusCode = description?.statusCode;
207-
const grpcCode = description?.grpcCode;
208-
let details = description?.error?.details;
209-
228+
// data is SkyflowApiErrorLegacyBody['error']
229+
const legacyErr = err as SkyflowApiErrorLegacy;
230+
const errorData = legacyErr.body?.error;
231+
let description: string = errorData?.message || errorMessages.ERROR_OCCURRED;
232+
const statusCode: number | undefined = errorData?.http_code;
233+
const grpcCode: number | string | undefined = errorData?.grpc_code;
234+
let details: any = errorData?.details || [];
235+
210236
if (errorFromClient !== undefined) {
211-
details = Array.isArray(details)
212-
? [...details, { errorFromClient }]
213-
: [{ errorFromClient }];
237+
details = Array.isArray(details)
238+
? [...details, { errorFromClient }]
239+
: [{ errorFromClient }];
214240
}
215-
216-
description = description?.body?.error?.message || description;
217-
this.logAndRejectError(description, err, requestId, reject, statusCode, grpcCode, details, isNewFormat);
241+
242+
this.logAndRejectError(
243+
description,
244+
err,
245+
requestId,
246+
reject,
247+
statusCode,
248+
grpcCode,
249+
details,
250+
isNewFormat
251+
);
218252
}
219253
}
220-
221-
222-
private handleTextError(err: any, data: any, requestId: string, reject: Function, errorFromClient?: boolean) {
223-
const isNewFormat = !!err?.rawResponse
254+
255+
private handleTextError(
256+
err: SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy,
257+
data: SkyflowErrorData,
258+
requestId: string,
259+
reject: Function,
260+
errorFromClient?: boolean
261+
) {
262+
const isNewFormat = this.isSkyflowApiErrorNewFormat(err);
224263
let details: any = [];
225-
264+
226265
if (errorFromClient !== undefined) {
227266
details.push({ errorFromClient });
228267
}
229-
230-
const description = isNewFormat ? data?.message: data?.body?.error?.message;
231-
const status = isNewFormat ? data?.http_status : err?.body?.error?.http_status;
232-
const grpcCode = isNewFormat ? data?.grpc_code : err?.body?.error?.grpc_code;
233-
this.logAndRejectError(description, err, requestId, reject, status, grpcCode, details, isNewFormat);
268+
269+
let description: string;
270+
let status: number | undefined;
271+
let grpcCode: number | string | undefined;
272+
273+
if (isNewFormat) {
274+
const errorData = data as SkyflowApiErrorNewFormat['body']['error'];
275+
description = errorData?.message || errorMessages.ERROR_OCCURRED;
276+
status = errorData?.http_code;
277+
grpcCode = errorData?.grpc_code;
278+
} else {
279+
const legacyErr = err as SkyflowApiErrorLegacy;
280+
const errorData = legacyErr.body?.error;
281+
description = errorData?.message || errorMessages.ERROR_OCCURRED;
282+
status = errorData?.http_code;
283+
grpcCode = errorData?.grpc_code;
284+
}
285+
286+
this.logAndRejectError(
287+
description,
288+
err,
289+
requestId,
290+
reject,
291+
status,
292+
grpcCode,
293+
details,
294+
isNewFormat
295+
);
234296
}
235-
236-
237-
private handleGenericError(err: any, requestId: string, reject: Function, errorFromClient?: boolean) {
238-
const isNewFormat = !!err?.rawResponse;
239-
let description: any;
240-
let grpcCode: any;
297+
298+
private handleGenericError(
299+
err: SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy,
300+
requestId: string,
301+
reject: Function,
302+
errorFromClient?: boolean
303+
) {
304+
const isNewFormat = this.isSkyflowApiErrorNewFormat(err);
305+
let description: string;
306+
let grpcCode: number | string | undefined;
241307
let details: any = [];
242-
308+
243309
if (isNewFormat) {
244-
description = err?.body?.error?.message || errorMessages.GENERIC_API_ERROR || err?.message
245-
grpcCode = err?.body?.error?.grpc_code;
246-
details = err?.body?.error?.details || [];
310+
const errorData = (err as SkyflowApiErrorNewFormat).body?.error;
311+
description =
312+
errorData?.message ??
313+
(err as SkyflowApiErrorNewFormat).message ??
314+
errorMessages.GENERIC_API_ERROR;
315+
grpcCode = errorData?.grpc_code;
316+
details = errorData?.details || [];
247317
} else {
248-
description = err?.body?.error?.message || errorMessages.ERROR_OCCURRED;
318+
const legacyErr = err as SkyflowApiErrorLegacy;
319+
const errorData = legacyErr.body?.error;
320+
description = errorData?.message || errorMessages.ERROR_OCCURRED;
321+
grpcCode = errorData?.grpc_code;
322+
details = errorData?.details || [];
249323
}
250-
324+
251325
if (errorFromClient !== undefined) {
252326
details = Array.isArray(details)
253-
? [...details, { errorFromClient }]
254-
: [{ errorFromClient }];
327+
? [...details, { errorFromClient }]
328+
: [{ errorFromClient }];
255329
}
256-
257-
this.logAndRejectError(description, err, requestId, reject, undefined, grpcCode, details, isNewFormat);
330+
331+
this.logAndRejectError(
332+
description,
333+
err,
334+
requestId,
335+
reject,
336+
undefined,
337+
grpcCode,
338+
details,
339+
isNewFormat
340+
);
258341
}
259342

260343
private logAndRejectError(
261344
description: string,
262-
err: any,
345+
err: SkyflowApiErrorNewFormat | SkyflowApiErrorLegacy,
263346
requestId: string,
264347
reject: Function,
265348
httpStatus?: number,
266-
grpcCode?: number,
349+
grpcCode?: number | string,
267350
details?: any,
268351
isNewError?: boolean
269352
) {

‎src/vault/controller/detect/index.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import SkyflowError from "../../../error";
2424
import SKYFLOW_ERROR_CODE from "../../../error/codes";
2525
import GetDetectRunRequest from "../../model/request/get-detect-run";
2626
import Transformations from "../../model/options/deidentify-text/transformations";
27+
import { SkyflowAllError } from "../../types";
2728

2829
class DetectController {
2930

@@ -396,7 +397,7 @@ class DetectController {
396397
break;
397398

398399
}
399-
}).catch((error: any) => {
400+
}).catch((error: SkyflowAllError) => {
400401
printLog(logs.errorLogs[`${requestType}_REQUEST_REJECTED`], MessageType.ERROR, this.client.getLogLevel());
401402
this.client.failureResponse(error).catch((err) => reject(err))
402403
});

‎src/vault/types/index.ts‎

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import VaultController from "../controller/vault";
66
import ConnectionController from "../controller/connections";
77
import VaultClient from "../client";
88
import DetectController from "../controller/detect";
9+
import SkyflowError from "../../error";
910

1011
export interface SkyflowConfig {
1112
vaultConfigs?: VaultConfig[];
@@ -76,4 +77,47 @@ export interface ParsedInsertBatchResponse {
7677
export interface DetokenizeData {
7778
token: string;
7879
redactionType?: RedactionType;
79-
}
80+
}
81+
82+
export interface SkyflowApiErrorNewFormat {
83+
rawResponse: {
84+
headers: { get(key: string): string | undefined };
85+
};
86+
body: {
87+
error: {
88+
message: string;
89+
http_code?: number;
90+
grpc_code?: number | string;
91+
details?: any[];
92+
};
93+
};
94+
statusCode?: number;
95+
message?: string;
96+
}
97+
98+
export interface SkyflowApiErrorLegacyBody {
99+
error: {
100+
message: string;
101+
http_code?: number;
102+
grpc_code?: number | string;
103+
details?: any[];
104+
};
105+
}
106+
107+
export interface SkyflowApiErrorLegacy {
108+
headers: { get(key: string): string | undefined };
109+
body?: SkyflowApiErrorLegacyBody;
110+
statusCode?: number;
111+
message?: string;
112+
}
113+
114+
export type SkyflowAllError =
115+
| SkyflowApiErrorNewFormat
116+
| SkyflowApiErrorLegacy
117+
| SkyflowError
118+
| Error;
119+
120+
export type SkyflowErrorData =
121+
| SkyflowApiErrorNewFormat['body']['error']
122+
| SkyflowApiErrorLegacyBody['error']
123+
| undefined;

0 commit comments

Comments
 (0)