Skip to content

Commit d67b0fc

Browse files
anujachakrabortydependabot[bot]aaronzi
authored
fixing the error message format in integration test (#124)
* fixing the error message format in integration test * modified the error message format for all methods * modified the error handling logic and its corresponsding test cases * Bump typescript-eslint from 8.27.0 to 8.28.0 (#114) * Bump rollup from 4.37.0 to 4.38.0 (#117) * Bump typescript-eslint from 8.28.0 to 8.29.0 (#119) * Bump ts-jest from 29.2.6 to 29.3.1 (#118) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.2.6 to 29.3.1. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](kulshekhar/ts-jest@v29.2.6...v29.3.1) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump rollup from 4.38.0 to 4.39.0 (#122) * Bump eslint-plugin-prettier from 5.2.5 to 5.2.6 (#125) * Bump @types/node from 22.13.14 to 22.14.0 (#126) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.13.14 to 22.14.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.14.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump typedoc from 0.28.1 to 0.28.2 (#127) Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.28.1 to 0.28.2. - [Release notes](https://github.com/TypeStrong/TypeDoc/releases) - [Changelog](https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md) - [Commits](TypeStrong/typedoc@v0.28.1...v0.28.2) --- updated-dependencies: - dependency-name: typedoc dependency-version: 0.28.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump typescript from 5.8.2 to 5.8.3 (#128) Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.8.2 to 5.8.3. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml) - [Commits](https://github.com/microsoft/TypeScript/commits) --- updated-dependencies: - dependency-name: typescript dependency-version: 5.8.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump eslint from 9.23.0 to 9.24.0 (#129) Bumps [eslint](https://github.com/eslint/eslint) from 9.23.0 to 9.24.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](eslint/eslint@v9.23.0...v9.24.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 9.24.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @typescript-eslint/parser from 8.29.0 to 8.29.1 (#132) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.29.0 to 8.29.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.29.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.29.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump typescript-eslint from 8.29.0 to 8.29.1 (#130) Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.29.0 to 8.29.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.29.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: typescript-eslint dependency-version: 8.29.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump eslint-config-prettier from 10.1.1 to 10.1.2 (#133) Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 10.1.1 to 10.1.2. - [Release notes](https://github.com/prettier/eslint-config-prettier/releases) - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md) - [Commits](prettier/eslint-config-prettier@v10.1.1...v10.1.2) --- updated-dependencies: - dependency-name: eslint-config-prettier dependency-version: 10.1.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump rollup from 4.39.0 to 4.40.0 (#134) Bumps [rollup](https://github.com/rollup/rollup) from 4.39.0 to 4.40.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](rollup/rollup@v4.39.0...v4.40.0) --- updated-dependencies: - dependency-name: rollup dependency-version: 4.40.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @types/node from 22.14.0 to 22.14.1 (#135) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.14.0 to 22.14.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.14.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump ts-jest from 29.3.1 to 29.3.2 (#136) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.3.1 to 29.3.2. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](kulshekhar/ts-jest@v29.3.1...v29.3.2) --- updated-dependencies: - dependency-name: ts-jest dependency-version: 29.3.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * provided the final fix for error handling * Adds missing tests * Improves error handling to account for different error types * Finalizes error handling --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Aaron Zielstorff <aaron.zi@web.de>
1 parent 505b852 commit d67b0fc

File tree

6 files changed

+495
-50
lines changed

6 files changed

+495
-50
lines changed

src/clients/AasRepositoryClient.ts

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
AssetAdministrationShellRepositoryAPIApi as AasRepository,
1010
Configuration,
1111
PagedResultPagingMetadata,
12-
RequiredError,
12+
Result,
1313
} from '../generated';
1414
import { applyDefaults } from '../lib/apiConfig';
1515
import { base64Encode } from '../lib/base64Url';
@@ -21,6 +21,7 @@ import {
2121
convertCoreAssetInformationToApiAssetInformation,
2222
convertCoreReferenceToApiReference,
2323
} from '../lib/convertAasTypes';
24+
import { handleApiError } from '../lib/errorHandler';
2425

2526
export class AasRepositoryClient {
2627
/**
@@ -47,7 +48,7 @@ export class AasRepositoryClient {
4748
pagedResult: PagedResultPagingMetadata | undefined;
4849
result: AssetAdministrationShell[];
4950
},
50-
RequiredError
51+
Result
5152
>
5253
> {
5354
const { configuration, assetIds, idShort, limit, cursor } = options;
@@ -69,7 +70,8 @@ export class AasRepositoryClient {
6970
data: { pagedResult: result.pagingMetadata, result: shells },
7071
};
7172
} catch (err) {
72-
return { success: false, error: err as RequiredError };
73+
const customError = await handleApiError(err);
74+
return { success: false, error: customError };
7375
}
7476
}
7577

@@ -85,7 +87,7 @@ export class AasRepositoryClient {
8587
async postAssetAdministrationShell(options: {
8688
configuration: Configuration;
8789
assetAdministrationShell: AssetAdministrationShell;
88-
}): Promise<ApiResult<AssetAdministrationShell, RequiredError>> {
90+
}): Promise<ApiResult<AssetAdministrationShell, Result>> {
8991
const { configuration, assetAdministrationShell } = options;
9092

9193
try {
@@ -97,7 +99,8 @@ export class AasRepositoryClient {
9799

98100
return { success: true, data: convertApiAasToCoreAas(result) };
99101
} catch (err) {
100-
return { success: false, error: err as RequiredError };
102+
const customError = await handleApiError(err);
103+
return { success: false, error: customError };
101104
}
102105
}
103106

@@ -113,7 +116,7 @@ export class AasRepositoryClient {
113116
async deleteAssetAdministrationShellById(options: {
114117
configuration: Configuration;
115118
aasIdentifier: string;
116-
}): Promise<ApiResult<void, RequiredError>> {
119+
}): Promise<ApiResult<void, Result>> {
117120
const { configuration, aasIdentifier } = options;
118121

119122
try {
@@ -127,7 +130,8 @@ export class AasRepositoryClient {
127130

128131
return { success: true, data: result };
129132
} catch (err) {
130-
return { success: false, error: err as RequiredError };
133+
const customError = await handleApiError(err);
134+
return { success: false, error: customError };
131135
}
132136
}
133137

@@ -143,7 +147,7 @@ export class AasRepositoryClient {
143147
async getAssetAdministrationShellById(options: {
144148
configuration: Configuration;
145149
aasIdentifier: string;
146-
}): Promise<ApiResult<AssetAdministrationShell, RequiredError>> {
150+
}): Promise<ApiResult<AssetAdministrationShell, Result>> {
147151
const { configuration, aasIdentifier } = options;
148152

149153
try {
@@ -157,7 +161,8 @@ export class AasRepositoryClient {
157161

158162
return { success: true, data: convertApiAasToCoreAas(result) };
159163
} catch (err) {
160-
return { success: false, error: err as RequiredError };
164+
const customError = await handleApiError(err);
165+
return { success: false, error: customError };
161166
}
162167
}
163168

@@ -175,7 +180,7 @@ export class AasRepositoryClient {
175180
configuration: Configuration;
176181
aasIdentifier: string;
177182
assetAdministrationShell: AssetAdministrationShell;
178-
}): Promise<ApiResult<void, RequiredError>> {
183+
}): Promise<ApiResult<void, Result>> {
179184
const { configuration, aasIdentifier, assetAdministrationShell } = options;
180185

181186
try {
@@ -190,7 +195,8 @@ export class AasRepositoryClient {
190195

191196
return { success: true, data: result };
192197
} catch (err) {
193-
return { success: false, error: err as RequiredError };
198+
const customError = await handleApiError(err);
199+
return { success: false, error: customError };
194200
}
195201
}
196202

@@ -206,7 +212,7 @@ export class AasRepositoryClient {
206212
async getAssetInformation(options: {
207213
configuration: Configuration;
208214
aasIdentifier: string;
209-
}): Promise<ApiResult<AssetInformation, RequiredError>> {
215+
}): Promise<ApiResult<AssetInformation, Result>> {
210216
const { configuration, aasIdentifier } = options;
211217

212218
try {
@@ -223,7 +229,8 @@ export class AasRepositoryClient {
223229
data: convertApiAssetInformationToCoreAssetInformation(result),
224230
};
225231
} catch (err) {
226-
return { success: false, error: err as RequiredError };
232+
const customError = await handleApiError(err);
233+
return { success: false, error: customError };
227234
}
228235
}
229236

@@ -241,7 +248,7 @@ export class AasRepositoryClient {
241248
configuration: Configuration;
242249
aasIdentifier: string;
243250
assetInformation: AssetInformation;
244-
}): Promise<ApiResult<void, RequiredError>> {
251+
}): Promise<ApiResult<void, Result>> {
245252
const { configuration, aasIdentifier, assetInformation } = options;
246253

247254
try {
@@ -256,7 +263,8 @@ export class AasRepositoryClient {
256263

257264
return { success: true, data: result };
258265
} catch (err) {
259-
return { success: false, error: err as RequiredError };
266+
const customError = await handleApiError(err);
267+
return { success: false, error: customError };
260268
}
261269
}
262270

@@ -272,7 +280,7 @@ export class AasRepositoryClient {
272280
async deleteThumbnail(options: {
273281
configuration: Configuration;
274282
aasIdentifier: string;
275-
}): Promise<ApiResult<void, RequiredError>> {
283+
}): Promise<ApiResult<void, Result>> {
276284
const { configuration, aasIdentifier } = options;
277285
try {
278286
const apiInstance = new AasRepository(applyDefaults(configuration));
@@ -285,7 +293,8 @@ export class AasRepositoryClient {
285293

286294
return { success: true, data: result };
287295
} catch (err) {
288-
return { success: false, error: err as RequiredError };
296+
const customError = await handleApiError(err);
297+
return { success: false, error: customError };
289298
}
290299
}
291300

@@ -301,7 +310,7 @@ export class AasRepositoryClient {
301310
async getThumbnail(options: {
302311
configuration: Configuration;
303312
aasIdentifier: string;
304-
}): Promise<ApiResult<Blob, RequiredError>> {
313+
}): Promise<ApiResult<Blob, Result>> {
305314
const { configuration, aasIdentifier } = options;
306315

307316
try {
@@ -315,7 +324,8 @@ export class AasRepositoryClient {
315324

316325
return { success: true, data: result };
317326
} catch (err) {
318-
return { success: false, error: err as RequiredError };
327+
const customError = await handleApiError(err);
328+
return { success: false, error: customError };
319329
}
320330
}
321331

@@ -335,7 +345,7 @@ export class AasRepositoryClient {
335345
aasIdentifier: string;
336346
fileName: string;
337347
file: Blob;
338-
}): Promise<ApiResult<void, RequiredError>> {
348+
}): Promise<ApiResult<void, Result>> {
339349
const { configuration, aasIdentifier, fileName, file } = options;
340350

341351
try {
@@ -351,7 +361,8 @@ export class AasRepositoryClient {
351361

352362
return { success: true, data: result };
353363
} catch (err) {
354-
return { success: false, error: err as RequiredError };
364+
const customError = await handleApiError(err);
365+
return { success: false, error: customError };
355366
}
356367
}
357368

@@ -371,7 +382,7 @@ export class AasRepositoryClient {
371382
aasIdentifier: string;
372383
limit?: number;
373384
cursor?: string;
374-
}): Promise<ApiResult<{ pagedResult: PagedResultPagingMetadata | undefined; result: Reference[] }, RequiredError>> {
385+
}): Promise<ApiResult<{ pagedResult: PagedResultPagingMetadata | undefined; result: Reference[] }, Result>> {
375386
const { configuration, aasIdentifier, limit, cursor } = options;
376387

377388
try {
@@ -394,7 +405,8 @@ export class AasRepositoryClient {
394405
},
395406
};
396407
} catch (err) {
397-
return { success: false, error: err as RequiredError };
408+
const customError = await handleApiError(err);
409+
return { success: false, error: customError };
398410
}
399411
}
400412

@@ -412,7 +424,7 @@ export class AasRepositoryClient {
412424
configuration: Configuration;
413425
aasIdentifier: string;
414426
submodelReference: Reference;
415-
}): Promise<ApiResult<Reference, RequiredError>> {
427+
}): Promise<ApiResult<Reference, Result>> {
416428
const { configuration, aasIdentifier, submodelReference } = options;
417429

418430
try {
@@ -427,7 +439,8 @@ export class AasRepositoryClient {
427439

428440
return { success: true, data: convertApiReferenceToCoreReference(result) };
429441
} catch (err) {
430-
return { success: false, error: err as RequiredError };
442+
const customError = await handleApiError(err);
443+
return { success: false, error: customError };
431444
}
432445
}
433446

@@ -445,7 +458,7 @@ export class AasRepositoryClient {
445458
configuration: Configuration;
446459
aasIdentifier: string;
447460
submodelIdentifier: string;
448-
}): Promise<ApiResult<void, RequiredError>> {
461+
}): Promise<ApiResult<void, Result>> {
449462
const { configuration, aasIdentifier, submodelIdentifier } = options;
450463

451464
try {
@@ -461,7 +474,8 @@ export class AasRepositoryClient {
461474

462475
return { success: true, data: result };
463476
} catch (err) {
464-
return { success: false, error: err as RequiredError };
477+
const customError = await handleApiError(err);
478+
return { success: false, error: customError };
465479
}
466480
}
467481
}

src/lib/base64Url.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* @returns {string} The Base64 encoded string, converted to URL-safe format if requested.
1616
*/
1717
export function base64Encode(string: string, urlSafe: boolean = true): string {
18+
if (string === null || string === undefined) return '';
19+
1820
string = string.trim();
1921

2022
if (string === '') return '';
@@ -49,6 +51,8 @@ export function base64Encode(string: string, urlSafe: boolean = true): string {
4951
* @returns {string} The decoded string.
5052
*/
5153
export function base64Decode(urlSafeBase64String: string): string {
54+
if (urlSafeBase64String === null || urlSafeBase64String === undefined) return '';
55+
5256
urlSafeBase64String = urlSafeBase64String.trim();
5357

5458
if (urlSafeBase64String === '') return '';

src/lib/errorHandler.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { FetchError, Message, RequiredError, ResponseError, Result } from '../generated';
2+
3+
/**
4+
* Processes errors from API calls and standardizes them to a Result object
5+
* with a consistent messages array following the API spec guidelines.
6+
*
7+
* @param err The error thrown during an API call
8+
* @returns A standardized Result object containing error messages
9+
*/
10+
export async function handleApiError(err: unknown): Promise<Result> {
11+
try {
12+
// Check if the error already has the expected format with messages array
13+
const errorAny = err as any;
14+
if (errorAny?.messages && Array.isArray(errorAny.messages)) {
15+
return { messages: errorAny.messages };
16+
}
17+
18+
// Get current timestamp with millisecond precision as a string
19+
const timestamp = (new Date().getTime() / 1000).toString();
20+
21+
let message: Message = {
22+
code: '500',
23+
messageType: 'Exception',
24+
timestamp: timestamp,
25+
text: 'Unknown error',
26+
};
27+
28+
// Handle different error types
29+
if (err instanceof RequiredError) {
30+
message = {
31+
code: '400',
32+
messageType: 'Exception',
33+
text: err.message || `Required parameter missing: ${err.field}`,
34+
timestamp: timestamp,
35+
};
36+
} else if (err instanceof ResponseError) {
37+
// Try to parse response body for messages
38+
const responseBody = err.response;
39+
40+
try {
41+
// Check if the response already contains a messages array
42+
const responseData = responseBody && responseBody.json ? await responseBody.json() : null;
43+
44+
if (responseData?.messages && Array.isArray(responseData.messages)) {
45+
return { messages: responseData.messages };
46+
}
47+
48+
// Otherwise, create a message with the status code
49+
message = {
50+
code: err.response.status.toString(),
51+
messageType: 'Exception',
52+
text: err.message || `HTTP ${err.response.status} - Response returned an error code`,
53+
timestamp: timestamp,
54+
};
55+
} catch {
56+
// If we can't parse the body, create a basic message
57+
message = {
58+
code: err.response.status.toString(),
59+
messageType: 'Exception',
60+
text: `HTTP ${err.response.status} - Response returned an error code`,
61+
timestamp: timestamp,
62+
};
63+
}
64+
} else if (err instanceof FetchError) {
65+
message = {
66+
code: '0',
67+
messageType: 'Exception',
68+
text: err.message || 'Network request failed',
69+
timestamp: timestamp,
70+
};
71+
} else if (err instanceof Error) {
72+
message = {
73+
code: '500',
74+
messageType: 'Exception',
75+
text: err.message || 'Unknown error occurred',
76+
timestamp: timestamp,
77+
};
78+
}
79+
80+
return { messages: [message] };
81+
} catch (handlerError) {
82+
// If our error handler throws an error, capture that and return a fallback error
83+
console.error('Error in error handler:', handlerError);
84+
85+
// Get current timestamp with millisecond precision as a string for the fallback error
86+
const timestamp = (new Date().getTime() / 1000).toString();
87+
88+
return {
89+
messages: [
90+
{
91+
code: '500',
92+
messageType: 'Exception',
93+
text: 'An error occurred while processing another error',
94+
timestamp: timestamp,
95+
},
96+
],
97+
};
98+
}
99+
}

0 commit comments

Comments
 (0)