@bernierllc/chat-suite 1.4.0 → 2.0.1
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.
- package/CHANGELOG.md +19 -0
- package/__tests__/unit/errors.test.ts +42 -0
- package/dist/ChatSuite.js +9 -3
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +30 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/providers/ChatKitProvider.js +8 -4
- package/dist/providers/ExternalProviders.js +7 -9
- package/dist/services/ConfigManager.d.ts.map +1 -1
- package/dist/services/ConfigManager.js +7 -3
- package/dist/services/HealthMonitor.js +3 -3
- package/dist/services/MessageOrchestrator.js +3 -4
- package/dist/services/ProviderManager.js +3 -5
- package/dist/services/UserManager.js +1 -0
- package/dist/utils/error-handling.d.ts +8 -21
- package/dist/utils/error-handling.d.ts.map +1 -1
- package/dist/utils/error-handling.js +13 -34
- package/dist/utils/message-bridge.js +3 -2
- package/dist/utils/user-mapping.js +2 -4
- package/package.json +2 -2
- package/src/ChatSuite.ts +3 -3
- package/src/errors.ts +56 -0
- package/src/index.ts +7 -0
- package/src/services/ConfigManager.ts +7 -5
- package/src/services/MessageOrchestrator.ts +3 -3
- package/src/services/ProviderManager.ts +3 -3
- package/src/utils/error-handling.ts +15 -32
- package/tsconfig.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.1](https://github.com/bernierllc/tools/compare/@bernierllc/chat-suite@1.5.0...@bernierllc/chat-suite@2.0.1) (2026-05-20)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @bernierllc/chat-suite
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 1.5.0 (2026-05-20)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **validators-a11y-focus-order:** es2022, errors.ts with error.cause ([cfa9604](https://github.com/bernierllc/tools/commit/cfa96049636732b7961b5dab3a2a1cdc8a2a9480))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
# 1.4.0 (2026-05-20)
|
|
7
26
|
|
|
8
27
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { ChatSuiteError } from '../../src/errors';
|
|
10
|
+
|
|
11
|
+
describe('ChatSuiteError (ES2022)', () => {
|
|
12
|
+
it('preserves cause chain via native Error.cause', () => {
|
|
13
|
+
const original = new Error('boom');
|
|
14
|
+
const wrapped = new ChatSuiteError('outer failure', {
|
|
15
|
+
code: 'PROVIDER_ERROR',
|
|
16
|
+
cause: original
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(wrapped).toBeInstanceOf(ChatSuiteError);
|
|
20
|
+
expect(wrapped).toBeInstanceOf(Error);
|
|
21
|
+
expect(wrapped.message).toBe('outer failure');
|
|
22
|
+
expect(wrapped.code).toBe('PROVIDER_ERROR');
|
|
23
|
+
expect(wrapped.cause).toBe(original);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('defaults code to CHAT_SUITE_ERROR when not provided', () => {
|
|
27
|
+
const err = new ChatSuiteError('something went wrong');
|
|
28
|
+
expect(err.code).toBe('CHAT_SUITE_ERROR');
|
|
29
|
+
expect(err.cause).toBeUndefined();
|
|
30
|
+
expect(err.context).toBeUndefined();
|
|
31
|
+
expect(err.name).toBe('ChatSuiteError');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('preserves structured context', () => {
|
|
35
|
+
const err = new ChatSuiteError('routing failed', {
|
|
36
|
+
code: 'ROUTING_ERROR',
|
|
37
|
+
context: { providerType: 'slack', attempts: 3 }
|
|
38
|
+
});
|
|
39
|
+
expect(err.context).toEqual({ providerType: 'slack', attempts: 3 });
|
|
40
|
+
expect(err.code).toBe('ROUTING_ERROR');
|
|
41
|
+
});
|
|
42
|
+
});
|
package/dist/ChatSuite.js
CHANGED
|
@@ -22,9 +22,15 @@ const neverhub_1 = require("./neverhub");
|
|
|
22
22
|
* Main chat suite orchestration class
|
|
23
23
|
*/
|
|
24
24
|
class ChatSuite {
|
|
25
|
+
configManager;
|
|
26
|
+
userManager;
|
|
27
|
+
healthMonitor;
|
|
28
|
+
providerManager;
|
|
29
|
+
messageOrchestrator;
|
|
30
|
+
neverhubAdapter;
|
|
31
|
+
neverhubConnected = false;
|
|
32
|
+
initialized = false;
|
|
25
33
|
constructor(config) {
|
|
26
|
-
this.neverhubConnected = false;
|
|
27
|
-
this.initialized = false;
|
|
28
34
|
this.configManager = new ConfigManager_1.ConfigManager(config);
|
|
29
35
|
this.userManager = new UserManager_1.UserManager();
|
|
30
36
|
this.healthMonitor = new HealthMonitor_1.HealthMonitor();
|
|
@@ -44,7 +50,7 @@ class ChatSuite {
|
|
|
44
50
|
// 2. Initialize ChatKit provider (always required)
|
|
45
51
|
const chatKitResult = await this.initializeChatKitProvider(config);
|
|
46
52
|
if (!chatKitResult.success) {
|
|
47
|
-
throw new error_handling_1.ChatSuiteError(
|
|
53
|
+
throw new error_handling_1.ChatSuiteError(`Failed to initialize ChatKit: ${chatKitResult.error}`, { code: 'INITIALIZATION_ERROR' });
|
|
48
54
|
}
|
|
49
55
|
// 3. Initialize message bridge (if configured)
|
|
50
56
|
if (config.messageBridge) {
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error code union for chat-suite errors.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the previous `ChatSuiteErrorType` enum (removed in 2.0.0).
|
|
5
|
+
* Consumers should use the string literal directly, e.g. `'MESSAGE_ERROR'`.
|
|
6
|
+
*/
|
|
7
|
+
export type ChatSuiteErrorCode = 'CHAT_SUITE_ERROR' | 'PROVIDER_ERROR' | 'ROUTING_ERROR' | 'CONFIGURATION_ERROR' | 'INITIALIZATION_ERROR' | 'MESSAGE_ERROR' | 'NEVERHUB_ERROR';
|
|
8
|
+
/**
|
|
9
|
+
* Options bag accepted by `ChatSuiteError`.
|
|
10
|
+
*
|
|
11
|
+
* - `cause`: chained underlying error (ES2022 Error.cause).
|
|
12
|
+
* - `code`: a typed error code from {@link ChatSuiteErrorCode}.
|
|
13
|
+
* - `context`: arbitrary structured context.
|
|
14
|
+
*/
|
|
15
|
+
export interface ChatSuiteErrorOptions {
|
|
16
|
+
cause?: Error;
|
|
17
|
+
code?: ChatSuiteErrorCode;
|
|
18
|
+
context?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Custom error class for chat suite errors.
|
|
22
|
+
*
|
|
23
|
+
* Uses native ES2022 `Error.cause` for error chaining — read the underlying
|
|
24
|
+
* error via `error.cause`. Structured context lives on `error.context`.
|
|
25
|
+
*/
|
|
26
|
+
export declare class ChatSuiteError extends Error {
|
|
27
|
+
readonly code: ChatSuiteErrorCode;
|
|
28
|
+
readonly context?: Record<string, unknown>;
|
|
29
|
+
constructor(message: string, options?: ChatSuiteErrorOptions);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAC1B,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,qBAAqB,GACrB,sBAAsB,GACtB,eAAe,GACf,gBAAgB,CAAC;AAErB;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAE,kBAAkB,CAAC;IACzC,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEtC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;CAS7D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ChatSuiteError = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Custom error class for chat suite errors.
|
|
13
|
+
*
|
|
14
|
+
* Uses native ES2022 `Error.cause` for error chaining — read the underlying
|
|
15
|
+
* error via `error.cause`. Structured context lives on `error.context`.
|
|
16
|
+
*/
|
|
17
|
+
class ChatSuiteError extends Error {
|
|
18
|
+
code;
|
|
19
|
+
context;
|
|
20
|
+
constructor(message, options) {
|
|
21
|
+
super(message, options?.cause ? { cause: options.cause } : undefined);
|
|
22
|
+
this.name = 'ChatSuiteError';
|
|
23
|
+
this.code = options?.code ?? 'CHAT_SUITE_ERROR';
|
|
24
|
+
if (options?.context !== undefined) {
|
|
25
|
+
this.context = options.context;
|
|
26
|
+
}
|
|
27
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.ChatSuiteError = ChatSuiteError;
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC;AAG3B,cAAc,aAAa,CAAC;AAG5B,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAGlB,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC;AAG3B,cAAc,aAAa,CAAC;AAG5B,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -21,10 +21,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
21
21
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.ChatSuite = void 0;
|
|
24
|
+
exports.ChatSuiteError = exports.ChatSuite = void 0;
|
|
25
25
|
// Main export
|
|
26
26
|
var ChatSuite_1 = require("./ChatSuite");
|
|
27
27
|
Object.defineProperty(exports, "ChatSuite", { enumerable: true, get: function () { return ChatSuite_1.ChatSuite; } });
|
|
28
|
+
// Errors
|
|
29
|
+
var errors_1 = require("./errors");
|
|
30
|
+
Object.defineProperty(exports, "ChatSuiteError", { enumerable: true, get: function () { return errors_1.ChatSuiteError; } });
|
|
28
31
|
// Types
|
|
29
32
|
__exportStar(require("./types"), exports);
|
|
30
33
|
// Services
|
|
@@ -15,12 +15,16 @@ const chatkit_adapter_1 = require("@bernierllc/chatkit-adapter");
|
|
|
15
15
|
* ChatKit provider implementation
|
|
16
16
|
*/
|
|
17
17
|
class ChatKitProvider {
|
|
18
|
+
config;
|
|
19
|
+
type = 'chatkit';
|
|
20
|
+
name = '@bernierllc/chatkit-adapter';
|
|
21
|
+
adapter;
|
|
22
|
+
initialized = false;
|
|
23
|
+
errorCount = 0;
|
|
24
|
+
lastError;
|
|
25
|
+
initTime;
|
|
18
26
|
constructor(config = {}) {
|
|
19
27
|
this.config = config;
|
|
20
|
-
this.type = 'chatkit';
|
|
21
|
-
this.name = '@bernierllc/chatkit-adapter';
|
|
22
|
-
this.initialized = false;
|
|
23
|
-
this.errorCount = 0;
|
|
24
28
|
}
|
|
25
29
|
/**
|
|
26
30
|
* Initialize the ChatKit provider
|
|
@@ -15,9 +15,7 @@ exports.getAvailableProviders = getAvailableProviders;
|
|
|
15
15
|
* These are optional peer dependencies and will be implemented when those packages are available
|
|
16
16
|
*/
|
|
17
17
|
class ExternalProvider {
|
|
18
|
-
|
|
19
|
-
this.initialized = false;
|
|
20
|
-
}
|
|
18
|
+
initialized = false;
|
|
21
19
|
async initialize() {
|
|
22
20
|
throw new Error(`${this.name} provider is not implemented yet. ` +
|
|
23
21
|
`Install ${this.name} package to enable this provider.`);
|
|
@@ -64,10 +62,10 @@ class ExternalProvider {
|
|
|
64
62
|
* ```
|
|
65
63
|
*/
|
|
66
64
|
class SlackProvider extends ExternalProvider {
|
|
65
|
+
type = 'slack';
|
|
66
|
+
name = '@bernierllc/chat-integration-slack';
|
|
67
67
|
constructor(_config) {
|
|
68
68
|
super();
|
|
69
|
-
this.type = 'slack';
|
|
70
|
-
this.name = '@bernierllc/chat-integration-slack';
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
exports.SlackProvider = SlackProvider;
|
|
@@ -92,10 +90,10 @@ exports.SlackProvider = SlackProvider;
|
|
|
92
90
|
* ```
|
|
93
91
|
*/
|
|
94
92
|
class DiscordProvider extends ExternalProvider {
|
|
93
|
+
type = 'discord';
|
|
94
|
+
name = '@bernierllc/chat-integration-discord';
|
|
95
95
|
constructor(_config) {
|
|
96
96
|
super();
|
|
97
|
-
this.type = 'discord';
|
|
98
|
-
this.name = '@bernierllc/chat-integration-discord';
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
99
|
exports.DiscordProvider = DiscordProvider;
|
|
@@ -121,10 +119,10 @@ exports.DiscordProvider = DiscordProvider;
|
|
|
121
119
|
* ```
|
|
122
120
|
*/
|
|
123
121
|
class TeamsProvider extends ExternalProvider {
|
|
122
|
+
type = 'teams';
|
|
123
|
+
name = '@bernierllc/chat-integration-teams';
|
|
124
124
|
constructor(_config) {
|
|
125
125
|
super();
|
|
126
|
-
this.type = 'teams';
|
|
127
|
-
this.name = '@bernierllc/chat-integration-teams';
|
|
128
126
|
}
|
|
129
127
|
}
|
|
130
128
|
exports.TeamsProvider = TeamsProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigManager.d.ts","sourceRoot":"","sources":["../../src/services/ConfigManager.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAIhD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,eAAe,CAAmC;gBAE9C,aAAa,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAKpD;;OAEG;IACI,SAAS,IAAI,QAAQ,CAAC,eAAe,CAAC;IAI7C;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAM5D;;OAEG;IACI,GAAG,CAAC,CAAC,SAAS,MAAM,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;IAIvE;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAIrD;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIxC;;OAEG;IACI,cAAc,IAAI,IAAI;IAI7B;;OAEG;IACI,KAAK,IAAI,IAAI;IAKpB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACI,MAAM,IAAI,MAAM;IAIvB;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"ConfigManager.d.ts","sourceRoot":"","sources":["../../src/services/ConfigManager.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAIhD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,eAAe,CAAmC;gBAE9C,aAAa,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAKpD;;OAEG;IACI,SAAS,IAAI,QAAQ,CAAC,eAAe,CAAC;IAI7C;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAM5D;;OAEG;IACI,GAAG,CAAC,CAAC,SAAS,MAAM,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;IAIvE;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAIrD;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIxC;;OAEG;IACI,cAAc,IAAI,IAAI;IAI7B;;OAEG;IACI,KAAK,IAAI,IAAI;IAKpB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACI,MAAM,IAAI,MAAM;IAIvB;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAcpC"}
|
|
@@ -14,8 +14,9 @@ const error_handling_1 = require("../utils/error-handling");
|
|
|
14
14
|
* Manages chat suite configuration with validation and inheritance
|
|
15
15
|
*/
|
|
16
16
|
class ConfigManager {
|
|
17
|
+
config;
|
|
18
|
+
configOverrides = new Map();
|
|
17
19
|
constructor(initialConfig) {
|
|
18
|
-
this.configOverrides = new Map();
|
|
19
20
|
this.config = (0, config_inheritance_1.mergeConfigs)(config_inheritance_1.DEFAULT_SUITE_CONFIG, initialConfig || {});
|
|
20
21
|
this.validateConfiguration();
|
|
21
22
|
}
|
|
@@ -70,7 +71,7 @@ class ConfigManager {
|
|
|
70
71
|
validateConfiguration(config = this.config) {
|
|
71
72
|
const validation = (0, config_inheritance_1.validateConfig)(config);
|
|
72
73
|
if (!validation.valid) {
|
|
73
|
-
throw new error_handling_1.ChatSuiteError(
|
|
74
|
+
throw new error_handling_1.ChatSuiteError(`Configuration validation failed: ${validation.errors.join(', ')}`, { code: 'CONFIGURATION_ERROR' });
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
/**
|
|
@@ -88,7 +89,10 @@ class ConfigManager {
|
|
|
88
89
|
this.updateConfig(parsed);
|
|
89
90
|
}
|
|
90
91
|
catch (error) {
|
|
91
|
-
throw new error_handling_1.ChatSuiteError(
|
|
92
|
+
throw new error_handling_1.ChatSuiteError('Failed to parse configuration JSON', {
|
|
93
|
+
code: 'CONFIGURATION_ERROR',
|
|
94
|
+
cause: error instanceof Error ? error : undefined
|
|
95
|
+
});
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
}
|
|
@@ -12,9 +12,9 @@ exports.HealthMonitor = void 0;
|
|
|
12
12
|
* Monitors health of all chat suite components
|
|
13
13
|
*/
|
|
14
14
|
class HealthMonitor {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
providers = new Map();
|
|
16
|
+
lastHealthCheck;
|
|
17
|
+
healthCheckInterval;
|
|
18
18
|
/**
|
|
19
19
|
* Register a provider for health monitoring
|
|
20
20
|
*/
|
|
@@ -14,9 +14,8 @@ const error_handling_1 = require("../utils/error-handling");
|
|
|
14
14
|
* Orchestrates messages across all providers
|
|
15
15
|
*/
|
|
16
16
|
class MessageOrchestrator {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
17
|
+
messageBridge;
|
|
18
|
+
messages = new Map();
|
|
20
19
|
/**
|
|
21
20
|
* Set message bridge for cross-platform sync
|
|
22
21
|
*/
|
|
@@ -101,7 +100,7 @@ class MessageOrchestrator {
|
|
|
101
100
|
async bridgeMessage(sourceProvider, targetProvider, message) {
|
|
102
101
|
try {
|
|
103
102
|
if (!this.messageBridge) {
|
|
104
|
-
throw new error_handling_1.ChatSuiteError(
|
|
103
|
+
throw new error_handling_1.ChatSuiteError('Message bridge not configured', { code: 'CONFIGURATION_ERROR' });
|
|
105
104
|
}
|
|
106
105
|
if (!this.messageBridge.shouldBridge(sourceProvider.type, targetProvider.type)) {
|
|
107
106
|
return {
|
|
@@ -13,10 +13,8 @@ const error_handling_1 = require("../utils/error-handling");
|
|
|
13
13
|
* Manages all chat providers
|
|
14
14
|
*/
|
|
15
15
|
class ProviderManager {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.initializedProviders = new Set();
|
|
19
|
-
}
|
|
16
|
+
providers = new Map();
|
|
17
|
+
initializedProviders = new Set();
|
|
20
18
|
/**
|
|
21
19
|
* Register a provider
|
|
22
20
|
*/
|
|
@@ -171,7 +169,7 @@ class ProviderManager {
|
|
|
171
169
|
*/
|
|
172
170
|
unregisterProvider(providerType) {
|
|
173
171
|
if (this.initializedProviders.has(providerType)) {
|
|
174
|
-
throw new error_handling_1.ChatSuiteError(
|
|
172
|
+
throw new error_handling_1.ChatSuiteError(`Cannot unregister initialized provider ${providerType}. Shutdown first.`, { code: 'PROVIDER_ERROR' });
|
|
175
173
|
}
|
|
176
174
|
const deleted = this.providers.delete(providerType);
|
|
177
175
|
if (!deleted) {
|
|
@@ -1,27 +1,14 @@
|
|
|
1
1
|
import type { SuiteResult } from '../types';
|
|
2
|
+
import { ChatSuiteError, type ChatSuiteErrorCode, type ChatSuiteErrorOptions } from '../errors';
|
|
3
|
+
export { ChatSuiteError };
|
|
4
|
+
export type { ChatSuiteErrorCode, ChatSuiteErrorOptions };
|
|
2
5
|
/**
|
|
3
|
-
*
|
|
6
|
+
* Safely execute an async operation and return a SuiteResult.
|
|
7
|
+
*
|
|
8
|
+
* The optional `errorCode` parameter is used to prefix the returned error
|
|
9
|
+
* string (matching the previous `${type}: message` format).
|
|
4
10
|
*/
|
|
5
|
-
export declare
|
|
6
|
-
PROVIDER_ERROR = "PROVIDER_ERROR",
|
|
7
|
-
ROUTING_ERROR = "ROUTING_ERROR",
|
|
8
|
-
CONFIGURATION_ERROR = "CONFIGURATION_ERROR",
|
|
9
|
-
INITIALIZATION_ERROR = "INITIALIZATION_ERROR",
|
|
10
|
-
MESSAGE_ERROR = "MESSAGE_ERROR",
|
|
11
|
-
NEVERHUB_ERROR = "NEVERHUB_ERROR"
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Custom error class for chat suite errors
|
|
15
|
-
*/
|
|
16
|
-
export declare class ChatSuiteError extends Error {
|
|
17
|
-
type: ChatSuiteErrorType;
|
|
18
|
-
originalError?: Error | undefined;
|
|
19
|
-
constructor(type: ChatSuiteErrorType, message: string, originalError?: Error | undefined);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Safely execute an async operation and return a SuiteResult
|
|
23
|
-
*/
|
|
24
|
-
export declare function safeExecute<T>(operation: () => Promise<T>, errorType?: ChatSuiteErrorType): Promise<SuiteResult<T>>;
|
|
11
|
+
export declare function safeExecute<T>(operation: () => Promise<T>, errorCode?: ChatSuiteErrorCode): Promise<SuiteResult<T>>;
|
|
25
12
|
/**
|
|
26
13
|
* Retry an operation with exponential backoff
|
|
27
14
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/utils/error-handling.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/utils/error-handling.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC3B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;AAE1D;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,SAAS,GAAE,kBAAoC,GAC9C,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAWzB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,GACb,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWxD"}
|
|
@@ -7,40 +7,20 @@ The client may use and modify this code *only within the scope of the project it
|
|
|
7
7
|
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.ChatSuiteError =
|
|
10
|
+
exports.ChatSuiteError = void 0;
|
|
11
11
|
exports.safeExecute = safeExecute;
|
|
12
12
|
exports.retryOperation = retryOperation;
|
|
13
13
|
exports.formatError = formatError;
|
|
14
14
|
exports.isRetryableError = isRetryableError;
|
|
15
|
+
const errors_1 = require("../errors");
|
|
16
|
+
Object.defineProperty(exports, "ChatSuiteError", { enumerable: true, get: function () { return errors_1.ChatSuiteError; } });
|
|
15
17
|
/**
|
|
16
|
-
*
|
|
18
|
+
* Safely execute an async operation and return a SuiteResult.
|
|
19
|
+
*
|
|
20
|
+
* The optional `errorCode` parameter is used to prefix the returned error
|
|
21
|
+
* string (matching the previous `${type}: message` format).
|
|
17
22
|
*/
|
|
18
|
-
|
|
19
|
-
(function (ChatSuiteErrorType) {
|
|
20
|
-
ChatSuiteErrorType["PROVIDER_ERROR"] = "PROVIDER_ERROR";
|
|
21
|
-
ChatSuiteErrorType["ROUTING_ERROR"] = "ROUTING_ERROR";
|
|
22
|
-
ChatSuiteErrorType["CONFIGURATION_ERROR"] = "CONFIGURATION_ERROR";
|
|
23
|
-
ChatSuiteErrorType["INITIALIZATION_ERROR"] = "INITIALIZATION_ERROR";
|
|
24
|
-
ChatSuiteErrorType["MESSAGE_ERROR"] = "MESSAGE_ERROR";
|
|
25
|
-
ChatSuiteErrorType["NEVERHUB_ERROR"] = "NEVERHUB_ERROR";
|
|
26
|
-
})(ChatSuiteErrorType || (exports.ChatSuiteErrorType = ChatSuiteErrorType = {}));
|
|
27
|
-
/**
|
|
28
|
-
* Custom error class for chat suite errors
|
|
29
|
-
*/
|
|
30
|
-
class ChatSuiteError extends Error {
|
|
31
|
-
constructor(type, message, originalError) {
|
|
32
|
-
super(message);
|
|
33
|
-
this.type = type;
|
|
34
|
-
this.originalError = originalError;
|
|
35
|
-
this.name = 'ChatSuiteError';
|
|
36
|
-
Object.setPrototypeOf(this, ChatSuiteError.prototype);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
exports.ChatSuiteError = ChatSuiteError;
|
|
40
|
-
/**
|
|
41
|
-
* Safely execute an async operation and return a SuiteResult
|
|
42
|
-
*/
|
|
43
|
-
async function safeExecute(operation, errorType = ChatSuiteErrorType.MESSAGE_ERROR) {
|
|
23
|
+
async function safeExecute(operation, errorCode = 'MESSAGE_ERROR') {
|
|
44
24
|
try {
|
|
45
25
|
const data = await operation();
|
|
46
26
|
return { success: true, data };
|
|
@@ -49,7 +29,7 @@ async function safeExecute(operation, errorType = ChatSuiteErrorType.MESSAGE_ERR
|
|
|
49
29
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
50
30
|
return {
|
|
51
31
|
success: false,
|
|
52
|
-
error: `${
|
|
32
|
+
error: `${errorCode}: ${errorMessage}`
|
|
53
33
|
};
|
|
54
34
|
}
|
|
55
35
|
}
|
|
@@ -76,8 +56,8 @@ async function retryOperation(operation, maxRetries = 3, baseDelay = 1000) {
|
|
|
76
56
|
* Create a standardized error message
|
|
77
57
|
*/
|
|
78
58
|
function formatError(context, error) {
|
|
79
|
-
if (error instanceof ChatSuiteError) {
|
|
80
|
-
return `[${context}] ${error.
|
|
59
|
+
if (error instanceof errors_1.ChatSuiteError) {
|
|
60
|
+
return `[${context}] ${error.code}: ${error.message}`;
|
|
81
61
|
}
|
|
82
62
|
if (error instanceof Error) {
|
|
83
63
|
return `[${context}] ${error.message}`;
|
|
@@ -88,9 +68,8 @@ function formatError(context, error) {
|
|
|
88
68
|
* Check if an error is retryable
|
|
89
69
|
*/
|
|
90
70
|
function isRetryableError(error) {
|
|
91
|
-
if (error instanceof ChatSuiteError) {
|
|
92
|
-
return error.
|
|
93
|
-
error.type === ChatSuiteErrorType.MESSAGE_ERROR;
|
|
71
|
+
if (error instanceof errors_1.ChatSuiteError) {
|
|
72
|
+
return error.code === 'PROVIDER_ERROR' || error.code === 'MESSAGE_ERROR';
|
|
94
73
|
}
|
|
95
74
|
if (error instanceof Error) {
|
|
96
75
|
const message = error.message.toLowerCase();
|
|
@@ -12,10 +12,11 @@ exports.MessageBridge = void 0;
|
|
|
12
12
|
* Message bridge for cross-platform synchronization
|
|
13
13
|
*/
|
|
14
14
|
class MessageBridge {
|
|
15
|
+
config;
|
|
16
|
+
bridgedMessages = new Map();
|
|
17
|
+
channelMappings = new Map();
|
|
15
18
|
constructor(config) {
|
|
16
19
|
this.config = config;
|
|
17
|
-
this.bridgedMessages = new Map();
|
|
18
|
-
this.channelMappings = new Map();
|
|
19
20
|
if (config.channelMappings) {
|
|
20
21
|
this.channelMappings = config.channelMappings;
|
|
21
22
|
}
|
|
@@ -13,10 +13,8 @@ exports.createUnifiedId = createUnifiedId;
|
|
|
13
13
|
* User mapping storage
|
|
14
14
|
*/
|
|
15
15
|
class UserMapper {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.providerIndex = new Map(); // provider:userId -> unifiedId
|
|
19
|
-
}
|
|
16
|
+
identities = new Map();
|
|
17
|
+
providerIndex = new Map(); // provider:userId -> unifiedId
|
|
20
18
|
/**
|
|
21
19
|
* Create or update a user identity
|
|
22
20
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bernierllc/chat-suite",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Comprehensive chat orchestration suite with AI-powered routing",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"zod": "^3.22.0",
|
|
22
22
|
"@bernierllc/chat-ai-router": "1.6.0",
|
|
23
23
|
"@bernierllc/chat-analytics": "1.6.0",
|
|
24
|
-
"@bernierllc/chatkit-adapter": "1.
|
|
24
|
+
"@bernierllc/chatkit-adapter": "1.5.0",
|
|
25
25
|
"@bernierllc/neverhub-adapter": "0.4.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependenciesMeta": {
|
package/src/ChatSuite.ts
CHANGED
|
@@ -25,7 +25,7 @@ import { ProviderManager } from './services/ProviderManager';
|
|
|
25
25
|
import { MessageOrchestrator } from './services/MessageOrchestrator';
|
|
26
26
|
import { ChatKitProvider } from './providers/ChatKitProvider';
|
|
27
27
|
import { MessageBridge } from './utils/message-bridge';
|
|
28
|
-
import { ChatSuiteError
|
|
28
|
+
import { ChatSuiteError } from './utils/error-handling';
|
|
29
29
|
import {
|
|
30
30
|
registerWithNeverHub,
|
|
31
31
|
unregisterFromNeverHub,
|
|
@@ -74,8 +74,8 @@ export class ChatSuite {
|
|
|
74
74
|
const chatKitResult = await this.initializeChatKitProvider(config);
|
|
75
75
|
if (!chatKitResult.success) {
|
|
76
76
|
throw new ChatSuiteError(
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
`Failed to initialize ChatKit: ${chatKitResult.error}`,
|
|
78
|
+
{ code: 'INITIALIZATION_ERROR' }
|
|
79
79
|
);
|
|
80
80
|
}
|
|
81
81
|
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Typed error code union for chat-suite errors.
|
|
11
|
+
*
|
|
12
|
+
* Replaces the previous `ChatSuiteErrorType` enum (removed in 2.0.0).
|
|
13
|
+
* Consumers should use the string literal directly, e.g. `'MESSAGE_ERROR'`.
|
|
14
|
+
*/
|
|
15
|
+
export type ChatSuiteErrorCode =
|
|
16
|
+
| 'CHAT_SUITE_ERROR'
|
|
17
|
+
| 'PROVIDER_ERROR'
|
|
18
|
+
| 'ROUTING_ERROR'
|
|
19
|
+
| 'CONFIGURATION_ERROR'
|
|
20
|
+
| 'INITIALIZATION_ERROR'
|
|
21
|
+
| 'MESSAGE_ERROR'
|
|
22
|
+
| 'NEVERHUB_ERROR';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Options bag accepted by `ChatSuiteError`.
|
|
26
|
+
*
|
|
27
|
+
* - `cause`: chained underlying error (ES2022 Error.cause).
|
|
28
|
+
* - `code`: a typed error code from {@link ChatSuiteErrorCode}.
|
|
29
|
+
* - `context`: arbitrary structured context.
|
|
30
|
+
*/
|
|
31
|
+
export interface ChatSuiteErrorOptions {
|
|
32
|
+
cause?: Error;
|
|
33
|
+
code?: ChatSuiteErrorCode;
|
|
34
|
+
context?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Custom error class for chat suite errors.
|
|
39
|
+
*
|
|
40
|
+
* Uses native ES2022 `Error.cause` for error chaining — read the underlying
|
|
41
|
+
* error via `error.cause`. Structured context lives on `error.context`.
|
|
42
|
+
*/
|
|
43
|
+
export class ChatSuiteError extends Error {
|
|
44
|
+
public readonly code: ChatSuiteErrorCode;
|
|
45
|
+
public readonly context?: Record<string, unknown>;
|
|
46
|
+
|
|
47
|
+
constructor(message: string, options?: ChatSuiteErrorOptions) {
|
|
48
|
+
super(message, options?.cause ? { cause: options.cause } : undefined);
|
|
49
|
+
this.name = 'ChatSuiteError';
|
|
50
|
+
this.code = options?.code ?? 'CHAT_SUITE_ERROR';
|
|
51
|
+
if (options?.context !== undefined) {
|
|
52
|
+
this.context = options.context;
|
|
53
|
+
}
|
|
54
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,13 @@ Redistribution or use in other products or commercial offerings is not permitted
|
|
|
9
9
|
// Main export
|
|
10
10
|
export { ChatSuite } from './ChatSuite';
|
|
11
11
|
|
|
12
|
+
// Errors
|
|
13
|
+
export {
|
|
14
|
+
ChatSuiteError,
|
|
15
|
+
type ChatSuiteErrorCode,
|
|
16
|
+
type ChatSuiteErrorOptions
|
|
17
|
+
} from './errors';
|
|
18
|
+
|
|
12
19
|
// Types
|
|
13
20
|
export * from './types';
|
|
14
21
|
|
|
@@ -8,7 +8,7 @@ Redistribution or use in other products or commercial offerings is not permitted
|
|
|
8
8
|
|
|
9
9
|
import type { ChatSuiteConfig } from '../types';
|
|
10
10
|
import { DEFAULT_SUITE_CONFIG, mergeConfigs, validateConfig } from '../utils/config-inheritance';
|
|
11
|
-
import { ChatSuiteError
|
|
11
|
+
import { ChatSuiteError } from '../utils/error-handling';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Manages chat suite configuration with validation and inheritance
|
|
@@ -81,8 +81,8 @@ export class ConfigManager {
|
|
|
81
81
|
const validation = validateConfig(config);
|
|
82
82
|
if (!validation.valid) {
|
|
83
83
|
throw new ChatSuiteError(
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
`Configuration validation failed: ${validation.errors.join(', ')}`,
|
|
85
|
+
{ code: 'CONFIGURATION_ERROR' }
|
|
86
86
|
);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
@@ -103,9 +103,11 @@ export class ConfigManager {
|
|
|
103
103
|
this.updateConfig(parsed);
|
|
104
104
|
} catch (error) {
|
|
105
105
|
throw new ChatSuiteError(
|
|
106
|
-
ChatSuiteErrorType.CONFIGURATION_ERROR,
|
|
107
106
|
'Failed to parse configuration JSON',
|
|
108
|
-
|
|
107
|
+
{
|
|
108
|
+
code: 'CONFIGURATION_ERROR',
|
|
109
|
+
cause: error instanceof Error ? error : undefined
|
|
110
|
+
}
|
|
109
111
|
);
|
|
110
112
|
}
|
|
111
113
|
}
|
|
@@ -17,7 +17,7 @@ import type {
|
|
|
17
17
|
} from '../types';
|
|
18
18
|
import { MessagePriority, MessageStatus } from '../types';
|
|
19
19
|
import { MessageBridge } from '../utils/message-bridge';
|
|
20
|
-
import { ChatSuiteError,
|
|
20
|
+
import { ChatSuiteError, retryOperation } from '../utils/error-handling';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Orchestrates messages across all providers
|
|
@@ -135,8 +135,8 @@ export class MessageOrchestrator {
|
|
|
135
135
|
try {
|
|
136
136
|
if (!this.messageBridge) {
|
|
137
137
|
throw new ChatSuiteError(
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
'Message bridge not configured',
|
|
139
|
+
{ code: 'CONFIGURATION_ERROR' }
|
|
140
140
|
);
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -7,7 +7,7 @@ Redistribution or use in other products or commercial offerings is not permitted
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { Provider, ProviderType, SuiteResult } from '../types';
|
|
10
|
-
import { ChatSuiteError
|
|
10
|
+
import { ChatSuiteError } from '../utils/error-handling';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Provider registration information
|
|
@@ -204,8 +204,8 @@ export class ProviderManager {
|
|
|
204
204
|
public unregisterProvider(providerType: ProviderType): SuiteResult<void> {
|
|
205
205
|
if (this.initializedProviders.has(providerType)) {
|
|
206
206
|
throw new ChatSuiteError(
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
`Cannot unregister initialized provider ${providerType}. Shutdown first.`,
|
|
208
|
+
{ code: 'PROVIDER_ERROR' }
|
|
209
209
|
);
|
|
210
210
|
}
|
|
211
211
|
|
|
@@ -7,40 +7,24 @@ Redistribution or use in other products or commercial offerings is not permitted
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { SuiteResult } from '../types';
|
|
10
|
+
import {
|
|
11
|
+
ChatSuiteError,
|
|
12
|
+
type ChatSuiteErrorCode,
|
|
13
|
+
type ChatSuiteErrorOptions
|
|
14
|
+
} from '../errors';
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
export enum ChatSuiteErrorType {
|
|
15
|
-
PROVIDER_ERROR = 'PROVIDER_ERROR',
|
|
16
|
-
ROUTING_ERROR = 'ROUTING_ERROR',
|
|
17
|
-
CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',
|
|
18
|
-
INITIALIZATION_ERROR = 'INITIALIZATION_ERROR',
|
|
19
|
-
MESSAGE_ERROR = 'MESSAGE_ERROR',
|
|
20
|
-
NEVERHUB_ERROR = 'NEVERHUB_ERROR'
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Custom error class for chat suite errors
|
|
25
|
-
*/
|
|
26
|
-
export class ChatSuiteError extends Error {
|
|
27
|
-
constructor(
|
|
28
|
-
public type: ChatSuiteErrorType,
|
|
29
|
-
message: string,
|
|
30
|
-
public originalError?: Error
|
|
31
|
-
) {
|
|
32
|
-
super(message);
|
|
33
|
-
this.name = 'ChatSuiteError';
|
|
34
|
-
Object.setPrototypeOf(this, ChatSuiteError.prototype);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
16
|
+
export { ChatSuiteError };
|
|
17
|
+
export type { ChatSuiteErrorCode, ChatSuiteErrorOptions };
|
|
37
18
|
|
|
38
19
|
/**
|
|
39
|
-
* Safely execute an async operation and return a SuiteResult
|
|
20
|
+
* Safely execute an async operation and return a SuiteResult.
|
|
21
|
+
*
|
|
22
|
+
* The optional `errorCode` parameter is used to prefix the returned error
|
|
23
|
+
* string (matching the previous `${type}: message` format).
|
|
40
24
|
*/
|
|
41
25
|
export async function safeExecute<T>(
|
|
42
26
|
operation: () => Promise<T>,
|
|
43
|
-
|
|
27
|
+
errorCode: ChatSuiteErrorCode = 'MESSAGE_ERROR'
|
|
44
28
|
): Promise<SuiteResult<T>> {
|
|
45
29
|
try {
|
|
46
30
|
const data = await operation();
|
|
@@ -49,7 +33,7 @@ export async function safeExecute<T>(
|
|
|
49
33
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
50
34
|
return {
|
|
51
35
|
success: false,
|
|
52
|
-
error: `${
|
|
36
|
+
error: `${errorCode}: ${errorMessage}`
|
|
53
37
|
};
|
|
54
38
|
}
|
|
55
39
|
}
|
|
@@ -88,7 +72,7 @@ export function formatError(
|
|
|
88
72
|
error: unknown
|
|
89
73
|
): string {
|
|
90
74
|
if (error instanceof ChatSuiteError) {
|
|
91
|
-
return `[${context}] ${error.
|
|
75
|
+
return `[${context}] ${error.code}: ${error.message}`;
|
|
92
76
|
}
|
|
93
77
|
if (error instanceof Error) {
|
|
94
78
|
return `[${context}] ${error.message}`;
|
|
@@ -101,8 +85,7 @@ export function formatError(
|
|
|
101
85
|
*/
|
|
102
86
|
export function isRetryableError(error: unknown): boolean {
|
|
103
87
|
if (error instanceof ChatSuiteError) {
|
|
104
|
-
return error.
|
|
105
|
-
error.type === ChatSuiteErrorType.MESSAGE_ERROR;
|
|
88
|
+
return error.code === 'PROVIDER_ERROR' || error.code === 'MESSAGE_ERROR';
|
|
106
89
|
}
|
|
107
90
|
if (error instanceof Error) {
|
|
108
91
|
const message = error.message.toLowerCase();
|
package/tsconfig.json
CHANGED