@scryme/chat 2.91.61 → 2.91.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,27 @@
1
- import { AxiosRequestConfig, AxiosError } from 'axios';
1
+ import { AxiosRequestConfig } from 'axios';
2
2
  export declare const setGlobalToken: (token: string | null) => void;
3
3
  export declare const getGlobalToken: () => string | null;
4
+ /**
5
+ * Custom SDK Error class for meaningful, developer-friendly error messages and structured error details.
6
+ */
7
+ export declare class ScrymeSDKError extends Error {
8
+ readonly status?: number;
9
+ readonly code?: string;
10
+ readonly data?: any;
11
+ readonly rawError?: any;
12
+ constructor(message: string, options?: {
13
+ status?: number;
14
+ code?: string;
15
+ data?: any;
16
+ rawError?: any;
17
+ });
18
+ }
19
+ export { ScrymeSDKError as ScrymeError };
20
+ /**
21
+ * Parses any error (AxiosError, Error, or unknown object) into a clean, meaningful ScrymeSDKError.
22
+ */
23
+ export declare function parseSDKError(error: any): ScrymeSDKError;
4
24
  export declare const AXIOS_INSTANCE: import("axios").AxiosInstance;
5
25
  export declare const customInstance: <T>(config: AxiosRequestConfig, options?: AxiosRequestConfig) => Promise<T>;
6
- export type ErrorType<Error> = AxiosError<Error>;
26
+ export type ErrorType<Error> = ScrymeSDKError;
7
27
  export type BodyType<Body> = Body;
@@ -1,3 +1,18 @@
1
+ var __extends = (this && this.__extends) || (function () {
2
+ var extendStatics = function (d, b) {
3
+ extendStatics = Object.setPrototypeOf ||
4
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6
+ return extendStatics(d, b);
7
+ };
8
+ return function (d, b) {
9
+ if (typeof b !== "function" && b !== null)
10
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
11
+ extendStatics(d, b);
12
+ function __() { this.constructor = d; }
13
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
+ };
15
+ })();
1
16
  var __assign = (this && this.__assign) || function () {
2
17
  __assign = Object.assign || function(t) {
3
18
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -46,11 +61,100 @@ export var setGlobalToken = function (token) {
46
61
  globalToken = token;
47
62
  };
48
63
  export var getGlobalToken = function () { return globalToken; };
64
+ /**
65
+ * Custom SDK Error class for meaningful, developer-friendly error messages and structured error details.
66
+ */
67
+ var ScrymeSDKError = /** @class */ (function (_super) {
68
+ __extends(ScrymeSDKError, _super);
69
+ function ScrymeSDKError(message, options) {
70
+ var _newTarget = this.constructor;
71
+ var _this = _super.call(this, message) || this;
72
+ _this.name = 'ScrymeSDKError';
73
+ _this.status = options === null || options === void 0 ? void 0 : options.status;
74
+ _this.code = options === null || options === void 0 ? void 0 : options.code;
75
+ _this.data = options === null || options === void 0 ? void 0 : options.data;
76
+ _this.rawError = options === null || options === void 0 ? void 0 : options.rawError;
77
+ Object.setPrototypeOf(_this, _newTarget.prototype);
78
+ return _this;
79
+ }
80
+ return ScrymeSDKError;
81
+ }(Error));
82
+ export { ScrymeSDKError };
83
+ export { ScrymeSDKError as ScrymeError };
84
+ /**
85
+ * Parses any error (AxiosError, Error, or unknown object) into a clean, meaningful ScrymeSDKError.
86
+ */
87
+ export function parseSDKError(error) {
88
+ if (error instanceof ScrymeSDKError) {
89
+ return error;
90
+ }
91
+ if (axios.isAxiosError(error)) {
92
+ var response = error.response;
93
+ var status_1 = response === null || response === void 0 ? void 0 : response.status;
94
+ var responseData = response === null || response === void 0 ? void 0 : response.data;
95
+ var code = error.code || (responseData && typeof responseData === 'object' ? responseData.code : undefined);
96
+ var message = void 0;
97
+ if (responseData) {
98
+ if (typeof responseData === 'string' && responseData.trim()) {
99
+ message = responseData;
100
+ }
101
+ else if (typeof responseData === 'object' && responseData !== null) {
102
+ if (Array.isArray(responseData.message)) {
103
+ message = responseData.message.filter(Boolean).join('; ');
104
+ }
105
+ else if (typeof responseData.message === 'string' && responseData.message.trim()) {
106
+ message = responseData.message;
107
+ }
108
+ else if (typeof responseData.error === 'string' && responseData.error.trim()) {
109
+ message = responseData.error;
110
+ }
111
+ else if (responseData.error && typeof responseData.error === 'object' && typeof responseData.error.message === 'string') {
112
+ message = responseData.error.message;
113
+ }
114
+ else if (typeof responseData.detail === 'string' && responseData.detail.trim()) {
115
+ message = responseData.detail;
116
+ }
117
+ }
118
+ }
119
+ if (!message) {
120
+ if (response === null || response === void 0 ? void 0 : response.statusText) {
121
+ message = "HTTP ".concat(status_1, ": ").concat(response.statusText);
122
+ }
123
+ else if (error.message && !error.message.startsWith('Request failed with status code')) {
124
+ message = error.message;
125
+ }
126
+ else if (status_1) {
127
+ message = "Request failed with status code ".concat(status_1);
128
+ }
129
+ else if (error.message) {
130
+ message = error.message;
131
+ }
132
+ else {
133
+ message = 'An unexpected error occurred during API request';
134
+ }
135
+ }
136
+ return new ScrymeSDKError(message, {
137
+ status: status_1,
138
+ code: code,
139
+ data: responseData,
140
+ rawError: error,
141
+ });
142
+ }
143
+ if (error instanceof Error) {
144
+ return new ScrymeSDKError(error.message, {
145
+ rawError: error,
146
+ });
147
+ }
148
+ return new ScrymeSDKError(typeof error === 'string' ? error : 'An unexpected error occurred', {
149
+ rawError: error,
150
+ });
151
+ }
49
152
  export var AXIOS_INSTANCE = axios.create({
50
153
  baseURL: getBaseURL(),
51
154
  timeout: 10000,
52
155
  withCredentials: true,
53
156
  });
157
+ AXIOS_INSTANCE.interceptors.response.use(function (response) { return response; }, function (error) { return Promise.reject(parseSDKError(error)); });
54
158
  AXIOS_INSTANCE.interceptors.request.use(function (config) {
55
159
  if (!config.baseURL) {
56
160
  config.baseURL = getBaseURL();
@@ -118,9 +222,13 @@ export var customInstance = function (config, options) {
118
222
  var source = axios.CancelToken.source();
119
223
  // Merge headers carefully so that options.headers does not overwrite config.headers completely
120
224
  var mergedHeaders = __assign(__assign({}, config.headers), options === null || options === void 0 ? void 0 : options.headers);
121
- var promise = AXIOS_INSTANCE(__assign(__assign(__assign({}, config), options), { headers: mergedHeaders, cancelToken: source.token })).then(function (_a) {
225
+ var promise = AXIOS_INSTANCE(__assign(__assign(__assign({}, config), options), { headers: mergedHeaders, cancelToken: source.token }))
226
+ .then(function (_a) {
122
227
  var data = _a.data;
123
228
  return data;
229
+ })
230
+ .catch(function (error) {
231
+ throw parseSDKError(error);
124
232
  });
125
233
  // @ts-ignore
126
234
  promise.cancel = function () {
package/dist/sdk.js CHANGED
@@ -55,7 +55,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
55
55
  return to.concat(ar || Array.prototype.slice.call(from));
56
56
  };
57
57
  import axios from 'axios';
58
- import { setGlobalToken } from './custom-instance';
58
+ import { setGlobalToken, parseSDKError } from './custom-instance';
59
59
  import { getSkyrmeChatAPI } from './generated/v3-server';
60
60
  /**
61
61
  * The primary client SDK class for accessing the Scryme Chat platform APIs.
@@ -173,7 +173,7 @@ var ScrymeSDK = /** @class */ (function () {
173
173
  case 3:
174
174
  error_1 = _e.sent();
175
175
  console.error('ScrymeSDK failed to authenticate via client_credentials:', error_1);
176
- throw error_1;
176
+ throw parseSDKError(error_1);
177
177
  case 4: return [2 /*return*/, this.token];
178
178
  }
179
179
  });
@@ -217,7 +217,7 @@ var ScrymeSDK = /** @class */ (function () {
217
217
  args[_i] = arguments[_i];
218
218
  }
219
219
  return __awaiter(_this, void 0, void 0, function () {
220
- var config, arity, cleanArgs, lastArg, isLastArgOptions, userOptions;
220
+ var config, arity, cleanArgs, lastArg, isLastArgOptions, userOptions, error_2;
221
221
  return __generator(this, function (_a) {
222
222
  switch (_a.label) {
223
223
  case 0: return [4 /*yield*/, this.getRequestConfig()];
@@ -242,7 +242,15 @@ var ScrymeSDK = /** @class */ (function () {
242
242
  }
243
243
  cleanArgs.push(config);
244
244
  }
245
- return [2 /*return*/, originalMethod.apply(void 0, cleanArgs)];
245
+ _a.label = 2;
246
+ case 2:
247
+ _a.trys.push([2, 4, , 5]);
248
+ return [4 /*yield*/, originalMethod.apply(void 0, cleanArgs)];
249
+ case 3: return [2 /*return*/, _a.sent()];
250
+ case 4:
251
+ error_2 = _a.sent();
252
+ throw parseSDKError(error_2);
253
+ case 5: return [2 /*return*/];
246
254
  }
247
255
  });
248
256
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scryme/chat",
3
- "version": "2.91.61",
3
+ "version": "2.91.87",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -0,0 +1,229 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import axios, { AxiosError } from 'axios';
3
+ import { ScrymeSDKError, ScrymeError, parseSDKError } from '../custom-instance';
4
+ import { ScrymeSDK } from '../sdk';
5
+
6
+ describe('ScrymeSDKError & parseSDKError', () => {
7
+ it('should construct ScrymeSDKError with status, code, data, and rawError', () => {
8
+ const rawErr = new Error('Raw');
9
+ const err = new ScrymeSDKError('Something went wrong', {
10
+ status: 400,
11
+ code: 'BAD_REQUEST',
12
+ data: { details: 'Invalid field' },
13
+ rawError: rawErr,
14
+ });
15
+
16
+ expect(err).toBeInstanceOf(Error);
17
+ expect(err).toBeInstanceOf(ScrymeSDKError);
18
+ expect(err).toBeInstanceOf(ScrymeError);
19
+ expect(err.name).toBe('ScrymeSDKError');
20
+ expect(err.message).toBe('Something went wrong');
21
+ expect(err.status).toBe(400);
22
+ expect(err.code).toBe('BAD_REQUEST');
23
+ expect(err.data).toEqual({ details: 'Invalid field' });
24
+ expect(err.rawError).toBe(rawErr);
25
+ });
26
+
27
+ it('should return existing ScrymeSDKError as is', () => {
28
+ const original = new ScrymeSDKError('Already parsed');
29
+ const result = parseSDKError(original);
30
+ expect(result).toBe(original);
31
+ });
32
+
33
+ it('should parse NestJS validation error arrays into joined message', () => {
34
+ const axiosError = new AxiosError(
35
+ 'Request failed with status code 400',
36
+ 'ERR_BAD_REQUEST',
37
+ undefined,
38
+ {},
39
+ {
40
+ status: 400,
41
+ statusText: 'Bad Request',
42
+ headers: {},
43
+ config: {} as any,
44
+ data: {
45
+ statusCode: 400,
46
+ error: 'Bad Request',
47
+ message: ['email must be an email', 'password is too short'],
48
+ },
49
+ }
50
+ );
51
+
52
+ const parsed = parseSDKError(axiosError);
53
+ expect(parsed).toBeInstanceOf(ScrymeSDKError);
54
+ expect(parsed.message).toBe('email must be an email; password is too short');
55
+ expect(parsed.status).toBe(400);
56
+ expect(parsed.code).toBe('ERR_BAD_REQUEST');
57
+ expect(parsed.data).toEqual({
58
+ statusCode: 400,
59
+ error: 'Bad Request',
60
+ message: ['email must be an email', 'password is too short'],
61
+ });
62
+ });
63
+
64
+ it('should parse standard NestJS error response with string message', () => {
65
+ const axiosError = new AxiosError(
66
+ 'Request failed with status code 404',
67
+ 'ERR_BAD_REQUEST',
68
+ undefined,
69
+ {},
70
+ {
71
+ status: 404,
72
+ statusText: 'Not Found',
73
+ headers: {},
74
+ config: {} as any,
75
+ data: {
76
+ statusCode: 404,
77
+ error: 'Not Found',
78
+ message: "Workspace 'acme' not found",
79
+ },
80
+ }
81
+ );
82
+
83
+ const parsed = parseSDKError(axiosError);
84
+ expect(parsed.message).toBe("Workspace 'acme' not found");
85
+ expect(parsed.status).toBe(404);
86
+ });
87
+
88
+ it('should parse error object format { error: "Unauthorized" }', () => {
89
+ const axiosError = new AxiosError(
90
+ 'Request failed with status code 401',
91
+ 'ERR_BAD_REQUEST',
92
+ undefined,
93
+ {},
94
+ {
95
+ status: 401,
96
+ statusText: 'Unauthorized',
97
+ headers: {},
98
+ config: {} as any,
99
+ data: {
100
+ error: 'Invalid session token',
101
+ },
102
+ }
103
+ );
104
+
105
+ const parsed = parseSDKError(axiosError);
106
+ expect(parsed.message).toBe('Invalid session token');
107
+ expect(parsed.status).toBe(401);
108
+ });
109
+
110
+ it('should parse nested error object format { error: { message: "Token expired" } }', () => {
111
+ const axiosError = new AxiosError(
112
+ 'Request failed with status code 401',
113
+ 'ERR_BAD_REQUEST',
114
+ undefined,
115
+ {},
116
+ {
117
+ status: 401,
118
+ statusText: 'Unauthorized',
119
+ headers: {},
120
+ config: {} as any,
121
+ data: {
122
+ error: {
123
+ message: 'Token expired',
124
+ code: 'TOKEN_EXPIRED',
125
+ },
126
+ },
127
+ }
128
+ );
129
+
130
+ const parsed = parseSDKError(axiosError);
131
+ expect(parsed.message).toBe('Token expired');
132
+ expect(parsed.status).toBe(401);
133
+ });
134
+
135
+ it('should parse string response data', () => {
136
+ const axiosError = new AxiosError(
137
+ 'Request failed with status code 502',
138
+ 'ERR_BAD_GATEWAY',
139
+ undefined,
140
+ {},
141
+ {
142
+ status: 502,
143
+ statusText: 'Bad Gateway',
144
+ headers: {},
145
+ config: {} as any,
146
+ data: 'Bad Gateway Error from Upstream',
147
+ }
148
+ );
149
+
150
+ const parsed = parseSDKError(axiosError);
151
+ expect(parsed.message).toBe('Bad Gateway Error from Upstream');
152
+ expect(parsed.status).toBe(502);
153
+ });
154
+
155
+ it('should handle network errors without response object', () => {
156
+ const axiosError = new AxiosError(
157
+ 'Network Error',
158
+ 'ERR_NETWORK',
159
+ undefined,
160
+ {},
161
+ undefined
162
+ );
163
+
164
+ const parsed = parseSDKError(axiosError);
165
+ expect(parsed.message).toBe('Network Error');
166
+ expect(parsed.status).toBeUndefined();
167
+ expect(parsed.code).toBe('ERR_NETWORK');
168
+ });
169
+
170
+ it('should handle timeout errors without response object', () => {
171
+ const axiosError = new AxiosError(
172
+ 'timeout of 10000ms exceeded',
173
+ 'ECONNABORTED',
174
+ undefined,
175
+ {},
176
+ undefined
177
+ );
178
+
179
+ const parsed = parseSDKError(axiosError);
180
+ expect(parsed.message).toBe('timeout of 10000ms exceeded');
181
+ expect(parsed.code).toBe('ECONNABORTED');
182
+ });
183
+
184
+ it('should handle standard non-Axios Error objects', () => {
185
+ const standardError = new TypeError('Failed to fetch');
186
+ const parsed = parseSDKError(standardError);
187
+
188
+ expect(parsed).toBeInstanceOf(ScrymeSDKError);
189
+ expect(parsed.message).toBe('Failed to fetch');
190
+ });
191
+
192
+ it('should handle primitive string errors', () => {
193
+ const parsed = parseSDKError('Custom error string');
194
+
195
+ expect(parsed).toBeInstanceOf(ScrymeSDKError);
196
+ expect(parsed.message).toBe('Custom error string');
197
+ });
198
+
199
+ it('should wrap M2M token fetch error into ScrymeSDKError', async () => {
200
+ const sdk = new ScrymeSDK({
201
+ baseURL: 'https://api.test.com',
202
+ clientId: 'invalid-id',
203
+ clientSecret: 'invalid-secret',
204
+ });
205
+
206
+ // Mock axios post failure
207
+ const postSpy = vi.spyOn(axios, 'post').mockRejectedValue(
208
+ new AxiosError('Request failed with status code 401', 'ERR_BAD_REQUEST', undefined, {}, {
209
+ status: 401,
210
+ statusText: 'Unauthorized',
211
+ headers: {},
212
+ config: {} as any,
213
+ data: { message: 'Invalid M2M client credentials' },
214
+ })
215
+ );
216
+
217
+ await expect(sdk.getOrFetchToken()).rejects.toThrow(ScrymeSDKError);
218
+
219
+ try {
220
+ await sdk.getOrFetchToken();
221
+ } catch (err: any) {
222
+ expect(err).toBeInstanceOf(ScrymeSDKError);
223
+ expect(err.message).toBe('Invalid M2M client credentials');
224
+ expect(err.status).toBe(401);
225
+ }
226
+
227
+ postSpy.mockRestore();
228
+ });
229
+ });
@@ -49,12 +49,115 @@ export const setGlobalToken = (token: string | null) => {
49
49
 
50
50
  export const getGlobalToken = () => globalToken;
51
51
 
52
+ /**
53
+ * Custom SDK Error class for meaningful, developer-friendly error messages and structured error details.
54
+ */
55
+ export class ScrymeSDKError extends Error {
56
+ public readonly status?: number;
57
+ public readonly code?: string;
58
+ public readonly data?: any;
59
+ public readonly rawError?: any;
60
+
61
+ constructor(
62
+ message: string,
63
+ options?: {
64
+ status?: number;
65
+ code?: string;
66
+ data?: any;
67
+ rawError?: any;
68
+ }
69
+ ) {
70
+ super(message);
71
+ this.name = 'ScrymeSDKError';
72
+ this.status = options?.status;
73
+ this.code = options?.code;
74
+ this.data = options?.data;
75
+ this.rawError = options?.rawError;
76
+
77
+ Object.setPrototypeOf(this, new.target.prototype);
78
+ }
79
+ }
80
+
81
+ export { ScrymeSDKError as ScrymeError };
82
+
83
+ /**
84
+ * Parses any error (AxiosError, Error, or unknown object) into a clean, meaningful ScrymeSDKError.
85
+ */
86
+ export function parseSDKError(error: any): ScrymeSDKError {
87
+ if (error instanceof ScrymeSDKError) {
88
+ return error;
89
+ }
90
+
91
+ if (axios.isAxiosError(error)) {
92
+ const response = error.response;
93
+ const status = response?.status;
94
+ const responseData = response?.data;
95
+ const code = error.code || (responseData && typeof responseData === 'object' ? responseData.code : undefined);
96
+
97
+ let message: string | undefined;
98
+
99
+ if (responseData) {
100
+ if (typeof responseData === 'string' && responseData.trim()) {
101
+ message = responseData;
102
+ } else if (typeof responseData === 'object' && responseData !== null) {
103
+ if (Array.isArray(responseData.message)) {
104
+ message = responseData.message.filter(Boolean).join('; ');
105
+ } else if (typeof responseData.message === 'string' && responseData.message.trim()) {
106
+ message = responseData.message;
107
+ } else if (typeof responseData.error === 'string' && responseData.error.trim()) {
108
+ message = responseData.error;
109
+ } else if (responseData.error && typeof responseData.error === 'object' && typeof responseData.error.message === 'string') {
110
+ message = responseData.error.message;
111
+ } else if (typeof responseData.detail === 'string' && responseData.detail.trim()) {
112
+ message = responseData.detail;
113
+ }
114
+ }
115
+ }
116
+
117
+ if (!message) {
118
+ if (response?.statusText) {
119
+ message = `HTTP ${status}: ${response.statusText}`;
120
+ } else if (error.message && !error.message.startsWith('Request failed with status code')) {
121
+ message = error.message;
122
+ } else if (status) {
123
+ message = `Request failed with status code ${status}`;
124
+ } else if (error.message) {
125
+ message = error.message;
126
+ } else {
127
+ message = 'An unexpected error occurred during API request';
128
+ }
129
+ }
130
+
131
+ return new ScrymeSDKError(message, {
132
+ status,
133
+ code,
134
+ data: responseData,
135
+ rawError: error,
136
+ });
137
+ }
138
+
139
+ if (error instanceof Error) {
140
+ return new ScrymeSDKError(error.message, {
141
+ rawError: error,
142
+ });
143
+ }
144
+
145
+ return new ScrymeSDKError(typeof error === 'string' ? error : 'An unexpected error occurred', {
146
+ rawError: error,
147
+ });
148
+ }
149
+
52
150
  export const AXIOS_INSTANCE = axios.create({
53
151
  baseURL: getBaseURL(),
54
152
  timeout: 10000,
55
153
  withCredentials: true,
56
154
  });
57
155
 
156
+ AXIOS_INSTANCE.interceptors.response.use(
157
+ response => response,
158
+ error => Promise.reject(parseSDKError(error))
159
+ );
160
+
58
161
  AXIOS_INSTANCE.interceptors.request.use(config => {
59
162
  if (!config.baseURL) {
60
163
  config.baseURL = getBaseURL();
@@ -144,7 +247,11 @@ export const customInstance = <T>(
144
247
  ...options,
145
248
  headers: mergedHeaders,
146
249
  cancelToken: source.token,
147
- }).then(({ data }) => data);
250
+ })
251
+ .then(({ data }) => data)
252
+ .catch(error => {
253
+ throw parseSDKError(error);
254
+ });
148
255
 
149
256
  // @ts-ignore
150
257
  promise.cancel = () => {
@@ -154,5 +261,5 @@ export const customInstance = <T>(
154
261
  return promise;
155
262
  };
156
263
 
157
- export type ErrorType<Error> = AxiosError<Error>;
264
+ export type ErrorType<Error> = ScrymeSDKError;
158
265
  export type BodyType<Body> = Body;
package/src/sdk.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import axios, { AxiosRequestConfig } from 'axios';
2
- import { setGlobalToken } from './custom-instance';
2
+ import { setGlobalToken, parseSDKError } from './custom-instance';
3
3
  import { getSkyrmeChatAPI } from './generated/v3-server';
4
4
  import type {
5
5
  V3ProvisionWorkspaceDto,
@@ -724,7 +724,7 @@ export class ScrymeSDK {
724
724
  }
725
725
  } catch (error) {
726
726
  console.error('ScrymeSDK failed to authenticate via client_credentials:', error);
727
- throw error;
727
+ throw parseSDKError(error);
728
728
  }
729
729
  }
730
730
 
@@ -788,7 +788,11 @@ export class ScrymeSDK {
788
788
  cleanArgs.push(config);
789
789
  }
790
790
 
791
- return (originalMethod as (...a: unknown[]) => unknown)(...cleanArgs);
791
+ try {
792
+ return await (originalMethod as (...a: unknown[]) => unknown)(...cleanArgs);
793
+ } catch (error) {
794
+ throw parseSDKError(error);
795
+ }
792
796
  };
793
797
  }
794
798
  return originalMethod;