Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ try {
// catch an error, identify if it is a SkyflowError
if (error instanceof SkyflowError) {
console.error("Skyflow Specific Error:", {
code: error.error?.http_code,
code: error.error?.httpCode,
message: error.message,
details: error.error?.details,
});
Expand Down
17 changes: 10 additions & 7 deletions docs/migrate_to_v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,13 @@ insertOptions.setContinueOnError(true); // Optional: Continue on partial errors
In V2, we have enriched the error details to provide better debugging capabilities.
The error response now includes:

- **`http_status`**: The HTTP status code. .
- **`grpc_code`**: The gRPC code associated with the error.
- **`httpStatus`**: The HTTP status text (e.g. `"Bad Request"`).
- **`grpcCode`**: The gRPC code associated with the error.
- **`httpCode`**: The HTTP status code number.
- **`details & message`**: A detailed description of the error.
- **`request_ID`**: A unique request identifier for easier debugging.
- **`requestId`**: A unique request identifier for easier debugging.

> **Deprecated names** — `http_status`, `grpc_code`, `http_code`, and `request_ID` still work but will log a deprecation warning and will be removed in v3. Use the camelCase names above.

#### V1 (Old) - Error Structure

Expand All @@ -256,11 +259,11 @@ The error response now includes:

```typescript
{
http_status?: string | number | null,
grpc_code?: string | number | null,
http_code: string | number | null,
httpStatus?: string | number | null,
grpcCode?: string | number | null,
httpCode?: string | number | null,
message: string,
request_ID?: string | null,
requestId?: string | null,
details?: Array<string> | null,
}
```
464 changes: 232 additions & 232 deletions src/error/codes/index.ts

Large diffs are not rendered by default.

32 changes: 28 additions & 4 deletions src/error/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ class SkyflowError extends Error {

constructor(errorCode: ISkyflowError, args: Array<string | number> = []) {
const formattedError: any = {
http_status: errorCode.http_status || BAD_REQUEST,
httpStatus: errorCode.httpStatus ?? errorCode.http_status ?? BAD_REQUEST,
details: errorCode.details || [],
requestId: errorCode.requestId || null,
grpc_code: errorCode.grpc_code || null,
http_code: errorCode.http_code,
grpcCode: errorCode.grpcCode ?? errorCode.grpc_code ?? null,
httpCode: errorCode.httpCode ?? errorCode.http_code,
message: args?.length > 0
? parameterizedString(errorCode.message, ...args)
: errorCode.message,
};

// Deprecated alias — remove after v3
// Deprecated aliases — remove after v3
Object.defineProperty(formattedError, 'request_ID', {
get() {
printLog(logs.warnLogs.DEPRECATED_REQUEST_ID_PROPERTY, MessageType.WARN, LogLevel.WARN);
Expand All @@ -26,6 +26,30 @@ class SkyflowError extends Error {
enumerable: true,
configurable: true,
});
Object.defineProperty(formattedError, 'http_code', {
get() {
printLog(logs.warnLogs.DEPRECATED_HTTP_CODE_PROPERTY, MessageType.WARN, LogLevel.WARN);
return this.httpCode;
},
enumerable: true,
configurable: true,
});
Object.defineProperty(formattedError, 'http_status', {
get() {
printLog(logs.warnLogs.DEPRECATED_HTTP_STATUS_PROPERTY, MessageType.WARN, LogLevel.WARN);
return this.httpStatus;
},
enumerable: true,
configurable: true,
});
Object.defineProperty(formattedError, 'grpc_code', {
get() {
printLog(logs.warnLogs.DEPRECATED_GRPC_CODE_PROPERTY, MessageType.WARN, LogLevel.WARN);
return this.grpcCode;
},
enumerable: true,
configurable: true,
});

super(formattedError.message);
this.error = formattedError;
Expand Down
8 changes: 4 additions & 4 deletions src/service-account/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,31 +325,31 @@ function failureResponse(err: ServiceAccountResponseError, options?: BearerToken
let description = err.body?.error?.message ?? err.body;
printLog(description, MessageType.ERROR, options?.logLevel);
reject(new SkyflowError({
http_code: err.body?.error?.http_code,
httpCode: err.body?.error?.http_code,
message: description,
requestId: requestId,
}));
} else if (contentType && contentType.includes(CONTENT_TYPE.TEXT_PLAIN)) {
let description = err.body;
printLog(description, MessageType.ERROR, options?.logLevel);
reject(new SkyflowError({
http_code: err.body?.error?.http_code,
httpCode: err.body?.error?.http_code,
message: description,
requestId: requestId
}));
} else {
let description = logs.errorLogs.ERROR_OCCURED;
printLog(description, MessageType.ERROR, options?.logLevel);
reject(new SkyflowError({
http_code: err.response?.status,
httpCode: err.response?.status,
message: description,
requestId: requestId
}));
}
} else {
printLog(err.message, MessageType.ERROR, options?.logLevel);
reject(new SkyflowError({
http_code: String(HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR),
httpCode: String(HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR),
message: err.message,
}))
}
Expand Down
9 changes: 8 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const SDK = {

export const SKYFLOW = {
ID: "skyflowId",
LEGACY_ID: "skyflow_id",
AUTH_HEADER_KEY: "x-skyflow-authorization",
} as const;

Expand Down Expand Up @@ -306,9 +307,15 @@ export const BOOLEAN_STRING = {


export interface ISkyflowError {
httpStatus?: string | number | null,
/** @deprecated Use httpStatus instead. Will be removed in v3. */
http_status?: string | number | null,
grpcCode?: string | number | null,
/** @deprecated Use grpcCode instead. Will be removed in v3. */
grpc_code?: string | number | null,
http_code: string | number | null | undefined,
httpCode?: string | number | null | undefined,
/** @deprecated Use httpCode instead. Will be removed in v3. */
http_code?: string | number | null | undefined,
message: string,
requestId?: string | null,
/** @deprecated Use requestId instead. Will be removed in v3. */
Expand Down
3 changes: 3 additions & 0 deletions src/utils/logs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ const logs = {
DEPRECATED_SKYFLOW_ID_PROPERTY: "[DEPRECATED] Property 'skyflow_id' is deprecated and will be removed in an upcoming release. Use 'skyflowId' instead.",
DEPRECATED_REQUEST_ID_PROPERTY: "[DEPRECATED] Property 'request_ID' is deprecated and will be removed in an upcoming release. Use 'requestId' instead.",
DEPRECATED_ROLE_IDS_PROPERTY: "[DEPRECATED] Property 'roleIDs' is deprecated and will be removed in an upcoming release. Use 'roleIds' instead.",
DEPRECATED_HTTP_CODE_PROPERTY: "[DEPRECATED] Property 'http_code' is deprecated and will be removed in an upcoming release. Use 'httpCode' instead.",
DEPRECATED_HTTP_STATUS_PROPERTY: "[DEPRECATED] Property 'http_status' is deprecated and will be removed in an upcoming release. Use 'httpStatus' instead.",
DEPRECATED_GRPC_CODE_PROPERTY: "[DEPRECATED] Property 'grpc_code' is deprecated and will be removed in an upcoming release. Use 'grpcCode' instead.",
}
};

Expand Down
18 changes: 13 additions & 5 deletions src/utils/validations/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CONFIG, Env, isValidURL, LogLevel, MessageType, RequestMethod, OrderByEnum, parameterizedString, printLog, RedactionType, SKYFLOW, TokenMode, API_KEY } from "..";
import { CONFIG, Env, HTTP_HEADER, isValidURL, LogLevel, MessageType, RequestMethod, OrderByEnum, parameterizedString, printLog, RedactionType, SKYFLOW, TokenMode, API_KEY } from "..";
import { V1Byot } from "../../ _generated_/rest/api";
import SkyflowError from "../../error";
import SKYFLOW_ERROR_CODE from "../../error/codes";
Expand Down Expand Up @@ -449,7 +449,7 @@ function validateUpdateInput(input: unknown): void {
const inputObject = input as { [key: string]: unknown };

// Exclude skyflow_id — it is the record identifier, not a data field to update
const entries = Object.entries(inputObject).filter(([key]) => key !== SKYFLOW.ID);
const entries = Object.entries(inputObject).filter(([key]) => key !== SKYFLOW.ID && key !== SKYFLOW.LEGACY_ID);

if (entries.length === 0) {
throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_RECORD_IN_UPDATE);
Expand Down Expand Up @@ -643,12 +643,18 @@ export const validateUpdateRequest = (updateRequest: UpdateRequest, updateOption
throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_TYPE_OF_UPDATE_DATA);
}

if (updateRequest?.data && !Object.prototype.hasOwnProperty.call(updateRequest.data, SKYFLOW.ID)) {
const hasNewId = Object.prototype.hasOwnProperty.call(updateRequest.data, SKYFLOW.ID);
const hasLegacyId = Object.prototype.hasOwnProperty.call(updateRequest.data, 'skyflow_id');
if (updateRequest?.data && !hasNewId && !hasLegacyId) {
printLog(logs.errorLogs.EMPTY_SKYFLOW_ID_IN_UPDATE, MessageType.ERROR, logLevel);
throw new SkyflowError(SKYFLOW_ERROR_CODE.MISSING_SKYFLOW_ID_IN_UPDATE);
}
if (hasLegacyId) {
printLog(logs.warnLogs.DEPRECATED_SKYFLOW_ID_PROPERTY, MessageType.WARN, logLevel);
}

if (typeof updateRequest.data[SKYFLOW.ID] !== 'string' || (updateRequest.data[SKYFLOW.ID] as string).trim().length === 0) {
const idValue = updateRequest.data[SKYFLOW.ID] ?? updateRequest.data[SKYFLOW.LEGACY_ID];
if (typeof idValue !== 'string' || (idValue as string).trim().length === 0) {
printLog(logs.errorLogs.INVALID_SKYFLOW_ID_IN_UPDATE, MessageType.ERROR, logLevel);
throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_SKYFLOW_ID_IN_UPDATE);
}
Expand Down Expand Up @@ -1257,7 +1263,9 @@ export const validateInvokeConnectionRequest = (invokeRequest: InvokeConnectionR
throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_PATH_PARAMS);
}

if (invokeRequest?.body && !isStringKeyValueMap(invokeRequest?.body)) {
const contentType = invokeRequest?.headers?.[HTTP_HEADER.CONTENT_TYPE] || invokeRequest?.headers?.[HTTP_HEADER.CONTENT_TYPE_LOWER] || '';
const isStringBody = typeof invokeRequest?.body === 'string';
if (invokeRequest?.body && !isStringKeyValueMap(invokeRequest?.body) && !(isStringBody && contentType)) {
throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_BODY);
}

Expand Down
6 changes: 3 additions & 3 deletions src/vault/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,11 @@ class VaultClient {
) {
printLog(description, MessageType.ERROR, this.getLogLevel());
reject(new SkyflowError({
http_code: isNewError ? (err?.statusCode ?? err?.body?.error?.http_code ?? HTTP_STATUS_CODE.BAD_REQUEST) : err?.body?.error?.http_code ?? HTTP_STATUS_CODE.BAD_REQUEST,
httpCode: isNewError ? (err?.statusCode ?? err?.body?.error?.http_code ?? HTTP_STATUS_CODE.BAD_REQUEST) : err?.body?.error?.http_code ?? HTTP_STATUS_CODE.BAD_REQUEST,
message: description,
requestId: requestId,
grpc_code: grpcCode,
http_status: httpStatus,
grpcCode: grpcCode,
httpStatus: httpStatus,
details: details,
}, []));
}
Expand Down
20 changes: 14 additions & 6 deletions src/vault/controller/vault/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,11 @@ class VaultController {
const body = record.Body as { records: StringKeyValueMapType[] };
if (body && Array.isArray(body.records)) {
body.records.forEach((field: StringKeyValueMapType) => {
const fieldTokens = field?.tokens;
const result: Record<string, unknown> = {
skyflowId: String(field?.skyflow_id),
requestIndex: index,
...(typeof field?.tokens === 'object' && field?.tokens !== null ? field.tokens : {})
...(typeof fieldTokens === 'object' && fieldTokens !== null ? fieldTokens : {})
};
this.addDeprecatedSkyflowIdAccessor(result);
response.success.push(result as InsertResponseType);
Expand Down Expand Up @@ -298,10 +299,17 @@ class VaultController {
validateUpdateRequest(request, options, this.client.getLogLevel());

const data = { ...request.data };
const skyflowId = data[SKYFLOW.ID];
let skyflowId = data[SKYFLOW.ID];
if (data[SKYFLOW.LEGACY_ID] !== undefined) {
printLog(logs.warnLogs.DEPRECATED_SKYFLOW_ID_PROPERTY, MessageType.WARN, this.client.getLogLevel());
if (skyflowId === undefined) {
skyflowId = data[SKYFLOW.LEGACY_ID];
}
delete data[SKYFLOW.LEGACY_ID];
}
delete data[SKYFLOW.ID];
const record = { fields: data, tokens: options?.getTokens() };
const strictMode = options?.getTokenMode() ? options?.getTokenMode() : V1Byot.Disable;
const strictMode = options?.getTokenMode() ? /* istanbul ignore next */ options?.getTokenMode() : V1Byot.Disable;
const updateData: RecordServiceUpdateRecordBody = {
record: record,
tokenization: options?.getReturnTokens(),
Expand All @@ -321,7 +329,7 @@ class VaultController {
printLog(logs.infoLogs.UPDATE_SUCCESS, MessageType.LOG, this.client.getLogLevel());
const updatedRecord: Record<string, unknown> = {
skyflowId: data.skyflow_id ?? '',
...data?.tokens
...data.tokens
};
this.addDeprecatedSkyflowIdAccessor(updatedRecord);
resolve(new UpdateResponse({ updatedField: updatedRecord as InsertResponseType, errors: null }));
Expand Down Expand Up @@ -469,7 +477,7 @@ class VaultController {
}

else if (options?.getFileObject() as File) {
fileBlob = options?.getFileObject();
fileBlob = options!.getFileObject();
}

const uploadFileV2Request: UploadFileV2Request = {
Expand Down Expand Up @@ -560,7 +568,7 @@ class VaultController {
//validations checks
validateDetokenizeRequest(request, options, this.client.getLogLevel());

const fields = request.data.map(record => ({ token: record.token, redaction: record?.redactionType || RedactionType.DEFAULT })) as Array<V1DetokenizeRecordRequest>;
const fields = request.data.map(record => ({ token: record.token, redaction: record.redactionType || RedactionType.DEFAULT })) as Array<V1DetokenizeRecordRequest>;
const detokenizePayload: V1DetokenizePayload = { detokenizationParameters: fields, continueOnError: options?.getContinueOnError(), downloadURL: options?.getDownloadUrl() };

this.handleRequest<RecordsResponse<Record<string, string>>>(
Expand Down
Loading
Loading