@tochii/errors 0.0.0-stage → 0.1.6
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 +49 -0
- package/LICENSE +21 -0
- package/README.md +51 -2
- package/csharp/Errors.cs +275 -0
- package/csharp/TochiRes.Errors.csproj +40 -0
- package/dist/codes-CCNEPVSz.d.ts +97 -0
- package/dist/codes.d.ts +2 -0
- package/dist/codes.js +136 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.js +28 -0
- package/dist/serialize-D7PDJ704.js +249 -0
- package/dist/serialize-xEOKnPuJ.d.ts +66 -0
- package/dist/serialize.d.ts +2 -0
- package/dist/serialize.js +3 -0
- package/package.json +53 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.6 (October 2026)
|
|
4
|
+
|
|
5
|
+
<!-- release:start -->
|
|
6
|
+
|
|
7
|
+
### CI
|
|
8
|
+
- Updated workflows ([#b1a1b89](https://github.com/tochiResources/errors/commit/b1a1b89) by [T0chi](https://github.com/T0chi))
|
|
9
|
+
|
|
10
|
+
<!-- release:end -->
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## 0.1.5 (October 2026)
|
|
14
|
+
|
|
15
|
+
### CI
|
|
16
|
+
- Added `dev` to `ci.yml`'s push branches ([#ff15308](https://github.com/tochiResources/errors/commit/ff15308) by [T0chi](https://github.com/T0chi))
|
|
17
|
+
|
|
18
|
+
## 0.1.4 (October 2026)
|
|
19
|
+
|
|
20
|
+
### CI
|
|
21
|
+
- Updated workflows ([#b2e3380](https://github.com/tochiResources/errors/commit/b2e3380) by [T0chi](https://github.com/T0chi))
|
|
22
|
+
|
|
23
|
+
## 0.1.3 (October 2026)
|
|
24
|
+
|
|
25
|
+
### Chores
|
|
26
|
+
- Set package to public ([#a8428d3](https://github.com/tochiResources/errors/commit/a8428d3) by [T0chi](https://github.com/T0chi))
|
|
27
|
+
|
|
28
|
+
## 0.1.2 (October 2026)
|
|
29
|
+
|
|
30
|
+
### CI
|
|
31
|
+
- Updated added `dev` branch ([#4b928a6](https://github.com/tochiResources/errors/commit/4b928a6) by [T0chi](https://github.com/T0chi))
|
|
32
|
+
- Updated changelog branch ([#59a6f69](https://github.com/tochiResources/errors/commit/59a6f69) by [T0chi](https://github.com/T0chi))
|
|
33
|
+
- Updated packaging flow ([#b4f3dbb](https://github.com/tochiResources/errors/commit/b4f3dbb) by [T0chi](https://github.com/T0chi))
|
|
34
|
+
### Chores
|
|
35
|
+
- Added `CHANGELOG.md` ([#1b53d03](https://github.com/tochiResources/errors/commit/1b53d03) by [T0chi](https://github.com/T0chi))
|
|
36
|
+
- Code cleanup ([#e914f15](https://github.com/tochiResources/errors/commit/e914f15) by [T0chi](https://github.com/T0chi))
|
|
37
|
+
- Update package.json description ([#edf61d0](https://github.com/tochiResources/errors/commit/edf61d0) by [T0chi](https://github.com/T0chi))
|
|
38
|
+
#### Errors
|
|
39
|
+
- Initialize repository ([#e39bad5](https://github.com/tochiResources/errors/commit/e39bad5) by [T0chi](https://github.com/T0chi))
|
|
40
|
+
|
|
41
|
+
## 0.1.1 (October 2026)
|
|
42
|
+
|
|
43
|
+
### CI
|
|
44
|
+
- Updated packaging flow ([#b4f3dbb](https://github.com/tochiResources/errors/commit/b4f3dbb) by T0chi)
|
|
45
|
+
### Chores
|
|
46
|
+
- Code cleanup ([#e914f15](https://github.com/tochiResources/errors/commit/e914f15) by T0chi)
|
|
47
|
+
- Update package.json description ([#edf61d0](https://github.com/tochiResources/errors/commit/edf61d0) by T0chi)
|
|
48
|
+
#### Errors
|
|
49
|
+
- Initialize repository ([#e39bad5](https://github.com/tochiResources/errors/commit/e39bad5) by T0chi)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tochiResources
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,52 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @tochii/errors
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/tochiResources/errors/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@tochii/errors)
|
|
5
|
+
|
|
6
|
+
Shared typed errors and stable error codes used in official tochiResources proejcts.
|
|
7
|
+
|
|
8
|
+
- **Stable codes**: the string value is part of the contract; never reuse or rename one. Both TS and C# switch on it.
|
|
9
|
+
- **Typed classes**: `instanceof ConfigError`, `instanceof IpcError`, per domain, all extending `TochiResError`.
|
|
10
|
+
- **Serializable**: `serializeError` / `deserializeError` move errors across JSON-RPC unchanged (message, code, context, cause chain).
|
|
11
|
+
- **Context**: every error can carry structured `context` for logging/telemetry.
|
|
12
|
+
|
|
13
|
+
## Projects using @tochii/errors
|
|
14
|
+
|
|
15
|
+
- [AeToOsb](https://github.com/tochiResources/AeToOsb)
|
|
16
|
+
- [AeBrew](https://github.com/tochiResources/AeBrew)
|
|
17
|
+
- [osu! Storyboarding toolkit](https://github.com/tochiResources/osb-toolkit)
|
|
18
|
+
- [tochiResources Adobe CEP](https://github.com/tochiResources/cep)
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { ConfigError, ErrorCode, isTochiResError, serializeError } from '@tochii/errors';
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
throw new ConfigError('app.name is required', {
|
|
27
|
+
code: ErrorCode.ConfigMissing,
|
|
28
|
+
context: { field: 'name' },
|
|
29
|
+
});
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (isTochiResError(error)) {
|
|
32
|
+
console.error(error.code, error.message, error.context);
|
|
33
|
+
socket.send(JSON.stringify(serializeError(error)));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Development
|
|
39
|
+
|
|
40
|
+
- **node 22.5+**, **yarn 4**, **vitest 5**, **tsdown**
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
yarn install
|
|
44
|
+
yarn build
|
|
45
|
+
yarn lint
|
|
46
|
+
yarn typecheck
|
|
47
|
+
yarn test
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## License
|
|
51
|
+
|
|
52
|
+
MIT. See [LICENSE](/LICENSE).
|
package/csharp/Errors.cs
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace TochiRes.Errors;
|
|
5
|
+
|
|
6
|
+
/// <summary>
|
|
7
|
+
/// Stable error codes shared with the TypeScript side (<c>@tochii/errors</c>).
|
|
8
|
+
/// Keep in sync with <c>src/codes.ts</c>. A code is part of the
|
|
9
|
+
/// public contract: never rename or reuse one — add a new code instead.
|
|
10
|
+
/// </summary>
|
|
11
|
+
public static class ErrorCodes
|
|
12
|
+
{
|
|
13
|
+
// General
|
|
14
|
+
public const string Unknown = "TOCHIRES_UNKNOWN";
|
|
15
|
+
public const string Internal = "TOCHIRES_INTERNAL";
|
|
16
|
+
|
|
17
|
+
// Config
|
|
18
|
+
public const string ConfigInvalid = "TOCHIRES_CONFIG_INVALID";
|
|
19
|
+
public const string ConfigMissing = "TOCHIRES_CONFIG_MISSING";
|
|
20
|
+
|
|
21
|
+
// Validation
|
|
22
|
+
public const string ValidationFailed = "TOCHIRES_VALIDATION_FAILED";
|
|
23
|
+
|
|
24
|
+
// API / HTTP boundary
|
|
25
|
+
public const string ApiBadRequest = "TOCHIRES_API_BAD_REQUEST";
|
|
26
|
+
public const string ApiUnauthorized = "TOCHIRES_API_UNAUTHORIZED";
|
|
27
|
+
public const string ApiForbidden = "TOCHIRES_API_FORBIDDEN";
|
|
28
|
+
public const string ApiNotFound = "TOCHIRES_API_NOT_FOUND";
|
|
29
|
+
public const string ApiConflict = "TOCHIRES_API_CONFLICT";
|
|
30
|
+
public const string ApiUnprocessable = "TOCHIRES_API_UNPROCESSABLE";
|
|
31
|
+
public const string ApiTooManyRequests = "TOCHIRES_API_TOO_MANY_REQUESTS";
|
|
32
|
+
public const string ApiTimeout = "TOCHIRES_API_TIMEOUT";
|
|
33
|
+
public const string ApiUnavailable = "TOCHIRES_API_UNAVAILABLE";
|
|
34
|
+
|
|
35
|
+
// IPC
|
|
36
|
+
public const string IpcTransport = "TOCHIRES_IPC_TRANSPORT";
|
|
37
|
+
public const string IpcProtocol = "TOCHIRES_IPC_PROTOCOL";
|
|
38
|
+
public const string IpcTimeout = "TOCHIRES_IPC_TIMEOUT";
|
|
39
|
+
public const string IpcAuth = "TOCHIRES_IPC_AUTH";
|
|
40
|
+
public const string IpcDisconnected = "TOCHIRES_IPC_DISCONNECTED";
|
|
41
|
+
public const string IpcBackpressure = "TOCHIRES_IPC_BACKPRESSURE";
|
|
42
|
+
|
|
43
|
+
// Codegen
|
|
44
|
+
public const string CodegenUnsupported = "TOCHIRES_CODEGEN_UNSUPPORTED";
|
|
45
|
+
public const string CodegenEmit = "TOCHIRES_CODEGEN_EMIT";
|
|
46
|
+
public const string CodegenRoundtrip = "TOCHIRES_CODEGEN_ROUNDTRIP";
|
|
47
|
+
|
|
48
|
+
// CSS
|
|
49
|
+
public const string CssParse = "TOCHIRES_CSS_PARSE";
|
|
50
|
+
public const string CssUnsupportedProperty = "TOCHIRES_CSS_UNSUPPORTED_PROPERTY";
|
|
51
|
+
public const string CssUnsupportedSelector = "TOCHIRES_CSS_UNSUPPORTED_SELECTOR";
|
|
52
|
+
|
|
53
|
+
// Native
|
|
54
|
+
public const string NativeModuleNotFound = "TOCHIRES_NATIVE_MODULE_NOT_FOUND";
|
|
55
|
+
public const string NativeMethodNotFound = "TOCHIRES_NATIVE_METHOD_NOT_FOUND";
|
|
56
|
+
public const string NativeCallFailed = "TOCHIRES_NATIVE_CALL_FAILED";
|
|
57
|
+
|
|
58
|
+
// Build
|
|
59
|
+
public const string BuildFailed = "TOCHIRES_BUILD_FAILED";
|
|
60
|
+
public const string BuildToolMissing = "TOCHIRES_BUILD_TOOL_MISSING";
|
|
61
|
+
|
|
62
|
+
// Package
|
|
63
|
+
public const string PackageFailed = "TOCHIRES_PACKAGE_FAILED";
|
|
64
|
+
public const string PackageSigning = "TOCHIRES_PACKAGE_SIGNING";
|
|
65
|
+
|
|
66
|
+
// Settings
|
|
67
|
+
public const string SettingsParse = "TOCHIRES_SETTINGS_PARSE";
|
|
68
|
+
public const string SettingsInvalid = "TOCHIRES_SETTINGS_INVALID";
|
|
69
|
+
|
|
70
|
+
// Path
|
|
71
|
+
public const string PathInvalid = "TOCHIRES_PATH_INVALID";
|
|
72
|
+
public const string PathAbsolute = "TOCHIRES_PATH_ABSOLUTE";
|
|
73
|
+
|
|
74
|
+
/// <summary>Every known code, for validation and diagnostics.</summary>
|
|
75
|
+
public static readonly IReadOnlyList<string> All = new[]
|
|
76
|
+
{
|
|
77
|
+
Unknown, Internal,
|
|
78
|
+
ConfigInvalid, ConfigMissing,
|
|
79
|
+
ValidationFailed,
|
|
80
|
+
ApiBadRequest, ApiUnauthorized, ApiForbidden, ApiNotFound, ApiConflict,
|
|
81
|
+
ApiUnprocessable, ApiTooManyRequests, ApiTimeout, ApiUnavailable,
|
|
82
|
+
IpcTransport, IpcProtocol, IpcTimeout, IpcAuth, IpcDisconnected, IpcBackpressure,
|
|
83
|
+
CodegenUnsupported, CodegenEmit, CodegenRoundtrip,
|
|
84
|
+
CssParse, CssUnsupportedProperty, CssUnsupportedSelector,
|
|
85
|
+
NativeModuleNotFound, NativeMethodNotFound, NativeCallFailed,
|
|
86
|
+
BuildFailed, BuildToolMissing,
|
|
87
|
+
PackageFailed, PackageSigning,
|
|
88
|
+
SettingsParse, SettingsInvalid,
|
|
89
|
+
PathInvalid, PathAbsolute,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
private static readonly IReadOnlyDictionary<string, string> CategoryByCode =
|
|
93
|
+
new Dictionary<string, string>(StringComparer.Ordinal)
|
|
94
|
+
{
|
|
95
|
+
[Unknown] = "general",
|
|
96
|
+
[Internal] = "general",
|
|
97
|
+
[ConfigInvalid] = "config",
|
|
98
|
+
[ConfigMissing] = "config",
|
|
99
|
+
[ValidationFailed] = "validation",
|
|
100
|
+
[ApiBadRequest] = "api",
|
|
101
|
+
[ApiUnauthorized] = "api",
|
|
102
|
+
[ApiForbidden] = "api",
|
|
103
|
+
[ApiNotFound] = "api",
|
|
104
|
+
[ApiConflict] = "api",
|
|
105
|
+
[ApiUnprocessable] = "api",
|
|
106
|
+
[ApiTooManyRequests] = "api",
|
|
107
|
+
[ApiTimeout] = "api",
|
|
108
|
+
[ApiUnavailable] = "api",
|
|
109
|
+
[IpcTransport] = "ipc",
|
|
110
|
+
[IpcProtocol] = "ipc",
|
|
111
|
+
[IpcTimeout] = "ipc",
|
|
112
|
+
[IpcAuth] = "ipc",
|
|
113
|
+
[IpcDisconnected] = "ipc",
|
|
114
|
+
[IpcBackpressure] = "ipc",
|
|
115
|
+
[CodegenUnsupported] = "codegen",
|
|
116
|
+
[CodegenEmit] = "codegen",
|
|
117
|
+
[CodegenRoundtrip] = "codegen",
|
|
118
|
+
[CssParse] = "css",
|
|
119
|
+
[CssUnsupportedProperty] = "css",
|
|
120
|
+
[CssUnsupportedSelector] = "css",
|
|
121
|
+
[NativeModuleNotFound] = "native",
|
|
122
|
+
[NativeMethodNotFound] = "native",
|
|
123
|
+
[NativeCallFailed] = "native",
|
|
124
|
+
[BuildFailed] = "build",
|
|
125
|
+
[BuildToolMissing] = "build",
|
|
126
|
+
[PackageFailed] = "package",
|
|
127
|
+
[PackageSigning] = "package",
|
|
128
|
+
[SettingsParse] = "settings",
|
|
129
|
+
[SettingsInvalid] = "settings",
|
|
130
|
+
[PathInvalid] = "path",
|
|
131
|
+
[PathAbsolute] = "path",
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/// <summary>Whether <paramref name="code"/> is one of the known stable codes.</summary>
|
|
135
|
+
public static bool IsKnown(string? code) => code is not null && CategoryByCode.ContainsKey(code);
|
|
136
|
+
|
|
137
|
+
/// <summary>The category a code belongs to, or <c>"general"</c> when unknown.</summary>
|
|
138
|
+
public static string CategoryOf(string? code) =>
|
|
139
|
+
code is not null && CategoryByCode.TryGetValue(code, out var category) ? category : "general";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/// <summary>
|
|
143
|
+
/// Base exception for every error defined by this package.
|
|
144
|
+
/// Mirrors <c>TochiResError</c> from the TypeScript implementation.
|
|
145
|
+
/// </summary>
|
|
146
|
+
public class TochiResException : Exception
|
|
147
|
+
{
|
|
148
|
+
/// <summary>Stable error code — part of the public contract.</summary>
|
|
149
|
+
public string Code { get; }
|
|
150
|
+
|
|
151
|
+
/// <summary>Coarse category derived from <see cref="Code"/>.</summary>
|
|
152
|
+
public string Category { get; }
|
|
153
|
+
|
|
154
|
+
/// <summary>Structured, JSON-safe context for logging and telemetry.</summary>
|
|
155
|
+
public IReadOnlyDictionary<string, object?>? Context { get; }
|
|
156
|
+
|
|
157
|
+
public TochiResException(
|
|
158
|
+
string code,
|
|
159
|
+
string message,
|
|
160
|
+
Exception? innerException = null,
|
|
161
|
+
IReadOnlyDictionary<string, object?>? context = null)
|
|
162
|
+
: base(message, innerException)
|
|
163
|
+
{
|
|
164
|
+
Code = code;
|
|
165
|
+
Category = ErrorCodes.CategoryOf(code);
|
|
166
|
+
Context = context;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/// <summary>Configuration is missing or failed validation.</summary>
|
|
171
|
+
public sealed class ConfigException : TochiResException
|
|
172
|
+
{
|
|
173
|
+
public ConfigException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
174
|
+
: base(ErrorCodes.ConfigInvalid, message, inner, context) { }
|
|
175
|
+
|
|
176
|
+
public ConfigException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
177
|
+
: base(code, message, inner, context) { }
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/// <summary>A payload, schema or argument failed validation.</summary>
|
|
181
|
+
public sealed class ValidationException : TochiResException
|
|
182
|
+
{
|
|
183
|
+
public ValidationException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
184
|
+
: base(ErrorCodes.ValidationFailed, message, inner, context) { }
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/// <summary>An API/HTTP boundary failure (bad request, auth, not found, conflict, …).</summary>
|
|
188
|
+
public sealed class ApiException : TochiResException
|
|
189
|
+
{
|
|
190
|
+
public ApiException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
191
|
+
: base(ErrorCodes.ApiBadRequest, message, inner, context) { }
|
|
192
|
+
|
|
193
|
+
public ApiException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
194
|
+
: base(code, message, inner, context) { }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/// <summary>An IPC transport, protocol, authentication or timeout failure.</summary>
|
|
198
|
+
public sealed class IpcException : TochiResException
|
|
199
|
+
{
|
|
200
|
+
public IpcException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
201
|
+
: base(ErrorCodes.IpcTransport, message, inner, context) { }
|
|
202
|
+
|
|
203
|
+
public IpcException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
204
|
+
: base(code, message, inner, context) { }
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/// <summary>A TS→C# code generator failed or hit an unsupported construct.</summary>
|
|
208
|
+
public sealed class CodegenException : TochiResException
|
|
209
|
+
{
|
|
210
|
+
public CodegenException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
211
|
+
: base(ErrorCodes.CodegenEmit, message, inner, context) { }
|
|
212
|
+
|
|
213
|
+
public CodegenException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
214
|
+
: base(code, message, inner, context) { }
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/// <summary>CSS input is invalid or outside the supported subset.</summary>
|
|
218
|
+
public sealed class CssException : TochiResException
|
|
219
|
+
{
|
|
220
|
+
public CssException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
221
|
+
: base(ErrorCodes.CssParse, message, inner, context) { }
|
|
222
|
+
|
|
223
|
+
public CssException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
224
|
+
: base(code, message, inner, context) { }
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/// <summary>A native module or method was missing, or a native call failed.</summary>
|
|
228
|
+
public sealed class NativeException : TochiResException
|
|
229
|
+
{
|
|
230
|
+
public NativeException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
231
|
+
: base(ErrorCodes.NativeCallFailed, message, inner, context) { }
|
|
232
|
+
|
|
233
|
+
public NativeException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
234
|
+
: base(code, message, inner, context) { }
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/// <summary>A build pipeline step failed or a required tool is missing.</summary>
|
|
238
|
+
public sealed class BuildException : TochiResException
|
|
239
|
+
{
|
|
240
|
+
public BuildException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
241
|
+
: base(ErrorCodes.BuildFailed, message, inner, context) { }
|
|
242
|
+
|
|
243
|
+
public BuildException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
244
|
+
: base(code, message, inner, context) { }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/// <summary>A packaging, signing or notarization step failed.</summary>
|
|
248
|
+
public sealed class PackageException : TochiResException
|
|
249
|
+
{
|
|
250
|
+
public PackageException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
251
|
+
: base(ErrorCodes.PackageFailed, message, inner, context) { }
|
|
252
|
+
|
|
253
|
+
public PackageException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
254
|
+
: base(code, message, inner, context) { }
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/// <summary>Settings text could not be parsed or failed validation.</summary>
|
|
258
|
+
public sealed class SettingsException : TochiResException
|
|
259
|
+
{
|
|
260
|
+
public SettingsException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
261
|
+
: base(ErrorCodes.SettingsInvalid, message, inner, context) { }
|
|
262
|
+
|
|
263
|
+
public SettingsException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
264
|
+
: base(code, message, inner, context) { }
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/// <summary>A path was malformed or violated the relative-path rule.</summary>
|
|
268
|
+
public sealed class PathException : TochiResException
|
|
269
|
+
{
|
|
270
|
+
public PathException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
271
|
+
: base(ErrorCodes.PathInvalid, message, inner, context) { }
|
|
272
|
+
|
|
273
|
+
public PathException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
|
|
274
|
+
: base(code, message, inner, context) { }
|
|
275
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
<PropertyGroup>
|
|
3
|
+
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
|
4
|
+
<LangVersion>latest</LangVersion>
|
|
5
|
+
<Nullable>enable</Nullable>
|
|
6
|
+
<ImplicitUsings>disable</ImplicitUsings>
|
|
7
|
+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
|
8
|
+
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
|
9
|
+
|
|
10
|
+
<PackageJsonPath>$(MSBuildThisFileDirectory)../package.json</PackageJsonPath>
|
|
11
|
+
|
|
12
|
+
<PackageJsonVersion>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"version"\s*:\s*"([^"]+)"').Groups[1].Value)</PackageJsonVersion>
|
|
13
|
+
<PackageJsonDescription>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"description"\s*:\s*"([^"]*)"').Groups[1].Value)</PackageJsonDescription>
|
|
14
|
+
<PackageJsonRepositoryUrl>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"repository"\s*:\s*\{[^}]*"url"\s*:\s*"(?:git\+)?(https?://[^"]+?)(?:\.git)?"').Groups[1].Value)</PackageJsonRepositoryUrl>
|
|
15
|
+
<PackageJsonAuthor>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"author"\s*:\s*"([^"]*)"').Groups[1].Value)</PackageJsonAuthor>
|
|
16
|
+
<PackageJsonLicense>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"license"\s*:\s*"([^"]*)"').Groups[1].Value)</PackageJsonLicense>
|
|
17
|
+
|
|
18
|
+
<PackageId>TochiRes.Errors</PackageId>
|
|
19
|
+
<Version>$(PackageJsonVersion)</Version>
|
|
20
|
+
<Authors>$(PackageJsonAuthor)</Authors>
|
|
21
|
+
<Description>$(PackageJsonDescription)</Description>
|
|
22
|
+
<PackageLicenseExpression>$(PackageJsonLicense)</PackageLicenseExpression>
|
|
23
|
+
<RepositoryUrl>$(PackageJsonRepositoryUrl)</RepositoryUrl>
|
|
24
|
+
<RepositoryType>git</RepositoryType>
|
|
25
|
+
<PackageProjectUrl>$(PackageJsonRepositoryUrl)</PackageProjectUrl>
|
|
26
|
+
<PackageReadmeFile>README.md</PackageReadmeFile>
|
|
27
|
+
<PackageTags>errors;exceptions;error-codes</PackageTags>
|
|
28
|
+
|
|
29
|
+
<IncludeSymbols>true</IncludeSymbols>
|
|
30
|
+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
|
31
|
+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
|
32
|
+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
|
33
|
+
<ContinuousIntegrationBuild Condition="'$(CI)' == 'true'">true</ContinuousIntegrationBuild>
|
|
34
|
+
</PropertyGroup>
|
|
35
|
+
|
|
36
|
+
<ItemGroup>
|
|
37
|
+
<None Include="../README.md" Pack="true" PackagePath="\" />
|
|
38
|
+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.403" PrivateAssets="all" />
|
|
39
|
+
</ItemGroup>
|
|
40
|
+
</Project>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//#region src/codes.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Stable error codes shared by the TypeScript and C# implementations.
|
|
4
|
+
*
|
|
5
|
+
* A code is part of the public contract: it is persisted in logs, sent across
|
|
6
|
+
* the JSON-RPC boundary and switched on by consumers (including the C# mirror
|
|
7
|
+
* in `Errors.cs`).
|
|
8
|
+
* Never rename or reuse a code — add a new one and deprecate the old.
|
|
9
|
+
*/
|
|
10
|
+
declare const ErrorCode: {
|
|
11
|
+
/** An error that could not be classified. */
|
|
12
|
+
readonly Unknown: "TOCHIRES_UNKNOWN";
|
|
13
|
+
/** An invariant inside the library was violated. */
|
|
14
|
+
readonly Internal: "TOCHIRES_INTERNAL";
|
|
15
|
+
/** A configuration object failed validation. */
|
|
16
|
+
readonly ConfigInvalid: "TOCHIRES_CONFIG_INVALID";
|
|
17
|
+
/** A required configuration field is missing. */
|
|
18
|
+
readonly ConfigMissing: "TOCHIRES_CONFIG_MISSING";
|
|
19
|
+
/** A generic validation failure (payload, schema, argument). */
|
|
20
|
+
readonly ValidationFailed: "TOCHIRES_VALIDATION_FAILED";
|
|
21
|
+
/** The request was malformed or failed validation at an API boundary. */
|
|
22
|
+
readonly ApiBadRequest: "TOCHIRES_API_BAD_REQUEST";
|
|
23
|
+
/** Authentication is required, or the session/token is invalid. */
|
|
24
|
+
readonly ApiUnauthorized: "TOCHIRES_API_UNAUTHORIZED";
|
|
25
|
+
/** The authenticated principal is not allowed to perform the action. */
|
|
26
|
+
readonly ApiForbidden: "TOCHIRES_API_FORBIDDEN";
|
|
27
|
+
/** The requested resource does not exist. */
|
|
28
|
+
readonly ApiNotFound: "TOCHIRES_API_NOT_FOUND";
|
|
29
|
+
/** The request conflicts with the current state of the resource. */
|
|
30
|
+
readonly ApiConflict: "TOCHIRES_API_CONFLICT";
|
|
31
|
+
/** The payload was well-formed but is semantically invalid. */
|
|
32
|
+
readonly ApiUnprocessable: "TOCHIRES_API_UNPROCESSABLE";
|
|
33
|
+
/** The caller exceeded an imposed rate limit. */
|
|
34
|
+
readonly ApiTooManyRequests: "TOCHIRES_API_TOO_MANY_REQUESTS";
|
|
35
|
+
/** An upstream dependency did not respond in time. */
|
|
36
|
+
readonly ApiTimeout: "TOCHIRES_API_TIMEOUT";
|
|
37
|
+
/** A downstream dependency is unavailable. */
|
|
38
|
+
readonly ApiUnavailable: "TOCHIRES_API_UNAVAILABLE";
|
|
39
|
+
/** The IPC transport could not be opened or used. */
|
|
40
|
+
readonly IpcTransport: "TOCHIRES_IPC_TRANSPORT";
|
|
41
|
+
/** A JSON-RPC envelope was malformed or violated the protocol. */
|
|
42
|
+
readonly IpcProtocol: "TOCHIRES_IPC_PROTOCOL";
|
|
43
|
+
/** A request did not receive a response in time. */
|
|
44
|
+
readonly IpcTimeout: "TOCHIRES_IPC_TIMEOUT";
|
|
45
|
+
/** Token authentication failed. */
|
|
46
|
+
readonly IpcAuth: "TOCHIRES_IPC_AUTH";
|
|
47
|
+
/** The peer disconnected before the operation completed. */
|
|
48
|
+
readonly IpcDisconnected: "TOCHIRES_IPC_DISCONNECTED";
|
|
49
|
+
/** A stream was paused because the consumer fell behind. */
|
|
50
|
+
readonly IpcBackpressure: "TOCHIRES_IPC_BACKPRESSURE";
|
|
51
|
+
/** A TypeScript construct has no C# codegen mapping. */
|
|
52
|
+
readonly CodegenUnsupported: "TOCHIRES_CODEGEN_UNSUPPORTED";
|
|
53
|
+
/** A generator failed while emitting an artifact. */
|
|
54
|
+
readonly CodegenEmit: "TOCHIRES_CODEGEN_EMIT";
|
|
55
|
+
/** Generated output did not round-trip back to its source. */
|
|
56
|
+
readonly CodegenRoundtrip: "TOCHIRES_CODEGEN_ROUNDTRIP";
|
|
57
|
+
/** CSS input could not be parsed. */
|
|
58
|
+
readonly CssParse: "TOCHIRES_CSS_PARSE";
|
|
59
|
+
/** A CSS property is outside the supported subset. */
|
|
60
|
+
readonly CssUnsupportedProperty: "TOCHIRES_CSS_UNSUPPORTED_PROPERTY";
|
|
61
|
+
/** A CSS selector is outside the supported subset. */
|
|
62
|
+
readonly CssUnsupportedSelector: "TOCHIRES_CSS_UNSUPPORTED_SELECTOR";
|
|
63
|
+
/** A native module was not registered on the C# host. */
|
|
64
|
+
readonly NativeModuleNotFound: "TOCHIRES_NATIVE_MODULE_NOT_FOUND";
|
|
65
|
+
/** A native method was not registered on a module. */
|
|
66
|
+
readonly NativeMethodNotFound: "TOCHIRES_NATIVE_METHOD_NOT_FOUND";
|
|
67
|
+
/** A native method threw or returned an error. */
|
|
68
|
+
readonly NativeCallFailed: "TOCHIRES_NATIVE_CALL_FAILED";
|
|
69
|
+
/** A build pipeline step failed. */
|
|
70
|
+
readonly BuildFailed: "TOCHIRES_BUILD_FAILED";
|
|
71
|
+
/** A required build tool (dotnet, esbuild, …) is unavailable. */
|
|
72
|
+
readonly BuildToolMissing: "TOCHIRES_BUILD_TOOL_MISSING";
|
|
73
|
+
/** A packaging step failed. */
|
|
74
|
+
readonly PackageFailed: "TOCHIRES_PACKAGE_FAILED";
|
|
75
|
+
/** Signing or notarization failed. */
|
|
76
|
+
readonly PackageSigning: "TOCHIRES_PACKAGE_SIGNING";
|
|
77
|
+
/** Settings text could not be parsed. */
|
|
78
|
+
readonly SettingsParse: "TOCHIRES_SETTINGS_PARSE";
|
|
79
|
+
/** Settings values failed validation against their spec. */
|
|
80
|
+
readonly SettingsInvalid: "TOCHIRES_SETTINGS_INVALID";
|
|
81
|
+
/** A path was malformed. */
|
|
82
|
+
readonly PathInvalid: "TOCHIRES_PATH_INVALID";
|
|
83
|
+
/** An absolute path was supplied where only relative paths are allowed. */
|
|
84
|
+
readonly PathAbsolute: "TOCHIRES_PATH_ABSOLUTE";
|
|
85
|
+
};
|
|
86
|
+
/** Union of every stable error code. */
|
|
87
|
+
type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
|
|
88
|
+
/** Coarse grouping used for reporting, filtering and C# exception types. */
|
|
89
|
+
type ErrorCategory = 'general' | 'config' | 'validation' | 'api' | 'ipc' | 'codegen' | 'css' | 'native' | 'build' | 'package' | 'settings' | 'path';
|
|
90
|
+
/** All codes, as an array — handy for exhaustiveness checks and docs. */
|
|
91
|
+
declare const ERROR_CODES: ErrorCode[];
|
|
92
|
+
/** Whether a value is one of the known stable codes. */
|
|
93
|
+
declare function isErrorCode(value: unknown): value is ErrorCode;
|
|
94
|
+
/** The category a code belongs to, or `'general'` for unknown codes. */
|
|
95
|
+
declare function categoryOf(code: ErrorCode): ErrorCategory;
|
|
96
|
+
//#endregion
|
|
97
|
+
export { isErrorCode as a, categoryOf as i, ErrorCategory as n, ErrorCode as r, ERROR_CODES as t };
|
package/dist/codes.d.ts
ADDED
package/dist/codes.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
//#region src/codes.ts
|
|
2
|
+
/**
|
|
3
|
+
* Stable error codes shared by the TypeScript and C# implementations.
|
|
4
|
+
*
|
|
5
|
+
* A code is part of the public contract: it is persisted in logs, sent across
|
|
6
|
+
* the JSON-RPC boundary and switched on by consumers (including the C# mirror
|
|
7
|
+
* in `Errors.cs`).
|
|
8
|
+
* Never rename or reuse a code — add a new one and deprecate the old.
|
|
9
|
+
*/
|
|
10
|
+
const ErrorCode = {
|
|
11
|
+
/** An error that could not be classified. */
|
|
12
|
+
Unknown: "TOCHIRES_UNKNOWN",
|
|
13
|
+
/** An invariant inside the library was violated. */
|
|
14
|
+
Internal: "TOCHIRES_INTERNAL",
|
|
15
|
+
/** A configuration object failed validation. */
|
|
16
|
+
ConfigInvalid: "TOCHIRES_CONFIG_INVALID",
|
|
17
|
+
/** A required configuration field is missing. */
|
|
18
|
+
ConfigMissing: "TOCHIRES_CONFIG_MISSING",
|
|
19
|
+
/** A generic validation failure (payload, schema, argument). */
|
|
20
|
+
ValidationFailed: "TOCHIRES_VALIDATION_FAILED",
|
|
21
|
+
/** The request was malformed or failed validation at an API boundary. */
|
|
22
|
+
ApiBadRequest: "TOCHIRES_API_BAD_REQUEST",
|
|
23
|
+
/** Authentication is required, or the session/token is invalid. */
|
|
24
|
+
ApiUnauthorized: "TOCHIRES_API_UNAUTHORIZED",
|
|
25
|
+
/** The authenticated principal is not allowed to perform the action. */
|
|
26
|
+
ApiForbidden: "TOCHIRES_API_FORBIDDEN",
|
|
27
|
+
/** The requested resource does not exist. */
|
|
28
|
+
ApiNotFound: "TOCHIRES_API_NOT_FOUND",
|
|
29
|
+
/** The request conflicts with the current state of the resource. */
|
|
30
|
+
ApiConflict: "TOCHIRES_API_CONFLICT",
|
|
31
|
+
/** The payload was well-formed but is semantically invalid. */
|
|
32
|
+
ApiUnprocessable: "TOCHIRES_API_UNPROCESSABLE",
|
|
33
|
+
/** The caller exceeded an imposed rate limit. */
|
|
34
|
+
ApiTooManyRequests: "TOCHIRES_API_TOO_MANY_REQUESTS",
|
|
35
|
+
/** An upstream dependency did not respond in time. */
|
|
36
|
+
ApiTimeout: "TOCHIRES_API_TIMEOUT",
|
|
37
|
+
/** A downstream dependency is unavailable. */
|
|
38
|
+
ApiUnavailable: "TOCHIRES_API_UNAVAILABLE",
|
|
39
|
+
/** The IPC transport could not be opened or used. */
|
|
40
|
+
IpcTransport: "TOCHIRES_IPC_TRANSPORT",
|
|
41
|
+
/** A JSON-RPC envelope was malformed or violated the protocol. */
|
|
42
|
+
IpcProtocol: "TOCHIRES_IPC_PROTOCOL",
|
|
43
|
+
/** A request did not receive a response in time. */
|
|
44
|
+
IpcTimeout: "TOCHIRES_IPC_TIMEOUT",
|
|
45
|
+
/** Token authentication failed. */
|
|
46
|
+
IpcAuth: "TOCHIRES_IPC_AUTH",
|
|
47
|
+
/** The peer disconnected before the operation completed. */
|
|
48
|
+
IpcDisconnected: "TOCHIRES_IPC_DISCONNECTED",
|
|
49
|
+
/** A stream was paused because the consumer fell behind. */
|
|
50
|
+
IpcBackpressure: "TOCHIRES_IPC_BACKPRESSURE",
|
|
51
|
+
/** A TypeScript construct has no C# codegen mapping. */
|
|
52
|
+
CodegenUnsupported: "TOCHIRES_CODEGEN_UNSUPPORTED",
|
|
53
|
+
/** A generator failed while emitting an artifact. */
|
|
54
|
+
CodegenEmit: "TOCHIRES_CODEGEN_EMIT",
|
|
55
|
+
/** Generated output did not round-trip back to its source. */
|
|
56
|
+
CodegenRoundtrip: "TOCHIRES_CODEGEN_ROUNDTRIP",
|
|
57
|
+
/** CSS input could not be parsed. */
|
|
58
|
+
CssParse: "TOCHIRES_CSS_PARSE",
|
|
59
|
+
/** A CSS property is outside the supported subset. */
|
|
60
|
+
CssUnsupportedProperty: "TOCHIRES_CSS_UNSUPPORTED_PROPERTY",
|
|
61
|
+
/** A CSS selector is outside the supported subset. */
|
|
62
|
+
CssUnsupportedSelector: "TOCHIRES_CSS_UNSUPPORTED_SELECTOR",
|
|
63
|
+
/** A native module was not registered on the C# host. */
|
|
64
|
+
NativeModuleNotFound: "TOCHIRES_NATIVE_MODULE_NOT_FOUND",
|
|
65
|
+
/** A native method was not registered on a module. */
|
|
66
|
+
NativeMethodNotFound: "TOCHIRES_NATIVE_METHOD_NOT_FOUND",
|
|
67
|
+
/** A native method threw or returned an error. */
|
|
68
|
+
NativeCallFailed: "TOCHIRES_NATIVE_CALL_FAILED",
|
|
69
|
+
/** A build pipeline step failed. */
|
|
70
|
+
BuildFailed: "TOCHIRES_BUILD_FAILED",
|
|
71
|
+
/** A required build tool (dotnet, esbuild, …) is unavailable. */
|
|
72
|
+
BuildToolMissing: "TOCHIRES_BUILD_TOOL_MISSING",
|
|
73
|
+
/** A packaging step failed. */
|
|
74
|
+
PackageFailed: "TOCHIRES_PACKAGE_FAILED",
|
|
75
|
+
/** Signing or notarization failed. */
|
|
76
|
+
PackageSigning: "TOCHIRES_PACKAGE_SIGNING",
|
|
77
|
+
/** Settings text could not be parsed. */
|
|
78
|
+
SettingsParse: "TOCHIRES_SETTINGS_PARSE",
|
|
79
|
+
/** Settings values failed validation against their spec. */
|
|
80
|
+
SettingsInvalid: "TOCHIRES_SETTINGS_INVALID",
|
|
81
|
+
/** A path was malformed. */
|
|
82
|
+
PathInvalid: "TOCHIRES_PATH_INVALID",
|
|
83
|
+
/** An absolute path was supplied where only relative paths are allowed. */
|
|
84
|
+
PathAbsolute: "TOCHIRES_PATH_ABSOLUTE"
|
|
85
|
+
};
|
|
86
|
+
const CATEGORY_BY_CODE = {
|
|
87
|
+
[ErrorCode.Unknown]: "general",
|
|
88
|
+
[ErrorCode.Internal]: "general",
|
|
89
|
+
[ErrorCode.ConfigInvalid]: "config",
|
|
90
|
+
[ErrorCode.ConfigMissing]: "config",
|
|
91
|
+
[ErrorCode.ValidationFailed]: "validation",
|
|
92
|
+
[ErrorCode.ApiBadRequest]: "api",
|
|
93
|
+
[ErrorCode.ApiUnauthorized]: "api",
|
|
94
|
+
[ErrorCode.ApiForbidden]: "api",
|
|
95
|
+
[ErrorCode.ApiNotFound]: "api",
|
|
96
|
+
[ErrorCode.ApiConflict]: "api",
|
|
97
|
+
[ErrorCode.ApiUnprocessable]: "api",
|
|
98
|
+
[ErrorCode.ApiTooManyRequests]: "api",
|
|
99
|
+
[ErrorCode.ApiTimeout]: "api",
|
|
100
|
+
[ErrorCode.ApiUnavailable]: "api",
|
|
101
|
+
[ErrorCode.IpcTransport]: "ipc",
|
|
102
|
+
[ErrorCode.IpcProtocol]: "ipc",
|
|
103
|
+
[ErrorCode.IpcTimeout]: "ipc",
|
|
104
|
+
[ErrorCode.IpcAuth]: "ipc",
|
|
105
|
+
[ErrorCode.IpcDisconnected]: "ipc",
|
|
106
|
+
[ErrorCode.IpcBackpressure]: "ipc",
|
|
107
|
+
[ErrorCode.CodegenUnsupported]: "codegen",
|
|
108
|
+
[ErrorCode.CodegenEmit]: "codegen",
|
|
109
|
+
[ErrorCode.CodegenRoundtrip]: "codegen",
|
|
110
|
+
[ErrorCode.CssParse]: "css",
|
|
111
|
+
[ErrorCode.CssUnsupportedProperty]: "css",
|
|
112
|
+
[ErrorCode.CssUnsupportedSelector]: "css",
|
|
113
|
+
[ErrorCode.NativeModuleNotFound]: "native",
|
|
114
|
+
[ErrorCode.NativeMethodNotFound]: "native",
|
|
115
|
+
[ErrorCode.NativeCallFailed]: "native",
|
|
116
|
+
[ErrorCode.BuildFailed]: "build",
|
|
117
|
+
[ErrorCode.BuildToolMissing]: "build",
|
|
118
|
+
[ErrorCode.PackageFailed]: "package",
|
|
119
|
+
[ErrorCode.PackageSigning]: "package",
|
|
120
|
+
[ErrorCode.SettingsParse]: "settings",
|
|
121
|
+
[ErrorCode.SettingsInvalid]: "settings",
|
|
122
|
+
[ErrorCode.PathInvalid]: "path",
|
|
123
|
+
[ErrorCode.PathAbsolute]: "path"
|
|
124
|
+
};
|
|
125
|
+
/** All codes, as an array — handy for exhaustiveness checks and docs. */
|
|
126
|
+
const ERROR_CODES = Object.values(ErrorCode);
|
|
127
|
+
/** Whether a value is one of the known stable codes. */
|
|
128
|
+
function isErrorCode(value) {
|
|
129
|
+
return typeof value === "string" && Object.hasOwn(CATEGORY_BY_CODE, value);
|
|
130
|
+
}
|
|
131
|
+
/** The category a code belongs to, or `'general'` for unknown codes. */
|
|
132
|
+
function categoryOf(code) {
|
|
133
|
+
return CATEGORY_BY_CODE[code] ?? "general";
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { ERROR_CODES, ErrorCode, categoryOf, isErrorCode };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { a as isErrorCode, i as categoryOf, n as ErrorCategory, r as ErrorCode, t as ERROR_CODES } from "./codes-CCNEPVSz.js";
|
|
2
|
+
import { a as TochiResErrorOptions, i as TochiResError, n as isSerializedError, o as serializeCause, r as serializeError, s as SerializedError, t as deserializeError } from "./serialize-xEOKnPuJ.js";
|
|
3
|
+
//#region src/errors/options.d.ts
|
|
4
|
+
/** Options shared by every domain error class (adds an optional code override). */
|
|
5
|
+
interface DomainErrorOptions extends TochiResErrorOptions {
|
|
6
|
+
/** Override the class's default code. */
|
|
7
|
+
code?: ErrorCode;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/errors/api.d.ts
|
|
11
|
+
/** An API/HTTP boundary failure (bad request, auth, not found, conflict, …). */
|
|
12
|
+
export declare class ApiError extends TochiResError {
|
|
13
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/errors/build.d.ts
|
|
17
|
+
/** A build pipeline step failed or a required tool is missing. */
|
|
18
|
+
export declare class BuildError extends TochiResError {
|
|
19
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/errors/codegen.d.ts
|
|
23
|
+
/** A TS→C# code generator failed or hit an unsupported construct. */
|
|
24
|
+
export declare class CodegenError extends TochiResError {
|
|
25
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/errors/config.d.ts
|
|
29
|
+
/** Configuration is missing or failed validation. */
|
|
30
|
+
export declare class ConfigError extends TochiResError {
|
|
31
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/errors/css.d.ts
|
|
35
|
+
/** CSS input is invalid or outside the supported subset. */
|
|
36
|
+
export declare class CssError extends TochiResError {
|
|
37
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/errors/ipc.d.ts
|
|
41
|
+
/** An IPC transport, protocol, authentication or timeout failure. */
|
|
42
|
+
export declare class IpcError extends TochiResError {
|
|
43
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/errors/native.d.ts
|
|
47
|
+
/** A native module or method was missing, or a native call failed. */
|
|
48
|
+
export declare class NativeError extends TochiResError {
|
|
49
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/errors/package.d.ts
|
|
53
|
+
/** A packaging, signing or notarization step failed. */
|
|
54
|
+
export declare class PackageError extends TochiResError {
|
|
55
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/errors/path.d.ts
|
|
59
|
+
/** A path was malformed or violated the relative-path rule. */
|
|
60
|
+
export declare class PathError extends TochiResError {
|
|
61
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/errors/settings.d.ts
|
|
65
|
+
/** Settings text could not be parsed or failed validation. */
|
|
66
|
+
export declare class SettingsError extends TochiResError {
|
|
67
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/errors/validation.d.ts
|
|
71
|
+
/** A payload, schema or argument failed validation. */
|
|
72
|
+
export declare class ValidationError extends TochiResError {
|
|
73
|
+
constructor(message: string, options?: DomainErrorOptions);
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/errors/index.d.ts
|
|
77
|
+
/** Constructor shape shared by every domain error class. */
|
|
78
|
+
type DomainErrorConstructor = new (message: string, options?: DomainErrorOptions) => TochiResError;
|
|
79
|
+
/**
|
|
80
|
+
* The domain error class responsible for a code, or `undefined` for generic
|
|
81
|
+
* codes (which use {@link TochiResError} directly).
|
|
82
|
+
*/
|
|
83
|
+
export declare function errorClassFor(code: ErrorCode): DomainErrorConstructor | undefined;
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/guard.d.ts
|
|
86
|
+
/** Narrow a value to {@link TochiResError}. */
|
|
87
|
+
export declare function isTochiResError(value: unknown): value is TochiResError;
|
|
88
|
+
/** Whether a value is a {@link TochiResError} carrying one of the given codes. */
|
|
89
|
+
export declare function hasErrorCode(value: unknown, ...codes: ErrorCode[]): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Coerce any thrown value into a {@link TochiResError}.
|
|
92
|
+
*
|
|
93
|
+
* Already-typed errors pass through unchanged; native `Error`s and arbitrary
|
|
94
|
+
* thrown values are wrapped with {@link ErrorCode.Unknown} and kept as `cause`.
|
|
95
|
+
*/
|
|
96
|
+
export declare function toTochiResError(value: unknown, fallbackMessage?: string): TochiResError;
|
|
97
|
+
/** Assert a condition, throwing a {@link TochiResError} with the given code if falsy. */
|
|
98
|
+
export declare function assertTochiRes(condition: unknown, code: ErrorCode, message: string, options?: TochiResErrorOptions): asserts condition;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { type DomainErrorConstructor, type DomainErrorOptions, ERROR_CODES, type ErrorCategory, ErrorCode, type SerializedError, TochiResError, type TochiResErrorOptions, categoryOf, deserializeError, isErrorCode, isSerializedError, serializeCause, serializeError };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ERROR_CODES, ErrorCode, categoryOf, isErrorCode } from "./codes.js";
|
|
2
|
+
import { _ as serializeCause, a as ValidationError, c as PackageError, d as CssError, f as ConfigError, g as TochiResError, h as ApiError, i as errorClassFor, l as NativeError, m as BuildError, n as isSerializedError, o as SettingsError, p as CodegenError, r as serializeError, s as PathError, t as deserializeError, u as IpcError } from "./serialize-D7PDJ704.js";
|
|
3
|
+
//#region src/guard.ts
|
|
4
|
+
/** Narrow a value to {@link TochiResError}. */
|
|
5
|
+
function isTochiResError(value) {
|
|
6
|
+
return value instanceof TochiResError;
|
|
7
|
+
}
|
|
8
|
+
/** Whether a value is a {@link TochiResError} carrying one of the given codes. */
|
|
9
|
+
function hasErrorCode(value, ...codes) {
|
|
10
|
+
return value instanceof TochiResError && codes.includes(value.code);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Coerce any thrown value into a {@link TochiResError}.
|
|
14
|
+
*
|
|
15
|
+
* Already-typed errors pass through unchanged; native `Error`s and arbitrary
|
|
16
|
+
* thrown values are wrapped with {@link ErrorCode.Unknown} and kept as `cause`.
|
|
17
|
+
*/
|
|
18
|
+
function toTochiResError(value, fallbackMessage = "Unknown error") {
|
|
19
|
+
if (value instanceof TochiResError) return value;
|
|
20
|
+
if (value instanceof Error) return new TochiResError(ErrorCode.Unknown, value.message, { cause: value });
|
|
21
|
+
return new TochiResError(ErrorCode.Unknown, typeof value === "string" ? value : fallbackMessage, { cause: value });
|
|
22
|
+
}
|
|
23
|
+
/** Assert a condition, throwing a {@link TochiResError} with the given code if falsy. */
|
|
24
|
+
function assertTochiRes(condition, code, message, options = {}) {
|
|
25
|
+
if (!condition) throw new TochiResError(code, message, options);
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { ApiError, BuildError, CodegenError, ConfigError, CssError, ERROR_CODES, ErrorCode, IpcError, NativeError, PackageError, PathError, SettingsError, TochiResError, ValidationError, assertTochiRes, categoryOf, deserializeError, errorClassFor, hasErrorCode, isErrorCode, isSerializedError, isTochiResError, serializeCause, serializeError, toTochiResError };
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { ErrorCode, categoryOf, isErrorCode } from "./codes.js";
|
|
2
|
+
//#region src/base.ts
|
|
3
|
+
/**
|
|
4
|
+
* Base class for every typed error in this package.
|
|
5
|
+
*
|
|
6
|
+
* Carries a stable {@link ErrorCode} (mirrored in C#), a derived
|
|
7
|
+
* {@link ErrorCategory}, optional structured context and an optional cause
|
|
8
|
+
* chain, and serializes to a {@link SerializedError} that survives JSON-RPC.
|
|
9
|
+
*/
|
|
10
|
+
var TochiResError = class extends Error {
|
|
11
|
+
/** Stable code — part of the public contract. */
|
|
12
|
+
code;
|
|
13
|
+
/** Coarse category derived from {@link code}. */
|
|
14
|
+
category;
|
|
15
|
+
/** Structured, JSON-safe context. */
|
|
16
|
+
context;
|
|
17
|
+
/** Underlying cause, if any. */
|
|
18
|
+
cause;
|
|
19
|
+
constructor(code, message, options = {}) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "TochiResError";
|
|
22
|
+
this.code = code;
|
|
23
|
+
this.category = categoryOf(code);
|
|
24
|
+
if (options.context !== void 0) this.context = options.context;
|
|
25
|
+
if (options.cause !== void 0) this.cause = options.cause;
|
|
26
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
27
|
+
}
|
|
28
|
+
/** Serialize this error (and its cause chain) to a wire-safe object. */
|
|
29
|
+
toJSON() {
|
|
30
|
+
const json = {
|
|
31
|
+
name: this.name,
|
|
32
|
+
code: this.code,
|
|
33
|
+
category: this.category,
|
|
34
|
+
message: this.message
|
|
35
|
+
};
|
|
36
|
+
if (this.stack) json.stack = this.stack;
|
|
37
|
+
if (this.context) json.context = this.context;
|
|
38
|
+
const cause = serializeCause(this.cause);
|
|
39
|
+
if (cause) json.cause = cause;
|
|
40
|
+
return json;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
/** Serialize any value used as a `cause` into a {@link SerializedError}. */
|
|
44
|
+
function serializeCause(value) {
|
|
45
|
+
if (value === void 0) return void 0;
|
|
46
|
+
if (value instanceof TochiResError) return value.toJSON();
|
|
47
|
+
if (value instanceof Error) {
|
|
48
|
+
const json = {
|
|
49
|
+
name: value.name || "Error",
|
|
50
|
+
code: ErrorCode.Unknown,
|
|
51
|
+
category: "general",
|
|
52
|
+
message: value.message
|
|
53
|
+
};
|
|
54
|
+
if (value.stack) json.stack = value.stack;
|
|
55
|
+
return json;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
name: "Error",
|
|
59
|
+
code: ErrorCode.Unknown,
|
|
60
|
+
category: "general",
|
|
61
|
+
message: stringifyUnknown$1(value)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function stringifyUnknown$1(value) {
|
|
65
|
+
if (typeof value === "string") return value;
|
|
66
|
+
try {
|
|
67
|
+
return JSON.stringify(value) ?? String(value);
|
|
68
|
+
} catch {
|
|
69
|
+
return String(value);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/errors/api.ts
|
|
74
|
+
/** An API/HTTP boundary failure (bad request, auth, not found, conflict, …). */
|
|
75
|
+
var ApiError = class extends TochiResError {
|
|
76
|
+
constructor(message, options = {}) {
|
|
77
|
+
super(options.code ?? ErrorCode.ApiBadRequest, message, options);
|
|
78
|
+
this.name = "ApiError";
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/errors/build.ts
|
|
83
|
+
/** A build pipeline step failed or a required tool is missing. */
|
|
84
|
+
var BuildError = class extends TochiResError {
|
|
85
|
+
constructor(message, options = {}) {
|
|
86
|
+
super(options.code ?? ErrorCode.BuildFailed, message, options);
|
|
87
|
+
this.name = "BuildError";
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/errors/codegen.ts
|
|
92
|
+
/** A TS→C# code generator failed or hit an unsupported construct. */
|
|
93
|
+
var CodegenError = class extends TochiResError {
|
|
94
|
+
constructor(message, options = {}) {
|
|
95
|
+
super(options.code ?? ErrorCode.CodegenEmit, message, options);
|
|
96
|
+
this.name = "CodegenError";
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/errors/config.ts
|
|
101
|
+
/** Configuration is missing or failed validation. */
|
|
102
|
+
var ConfigError = class extends TochiResError {
|
|
103
|
+
constructor(message, options = {}) {
|
|
104
|
+
super(options.code ?? ErrorCode.ConfigInvalid, message, options);
|
|
105
|
+
this.name = "ConfigError";
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/errors/css.ts
|
|
110
|
+
/** CSS input is invalid or outside the supported subset. */
|
|
111
|
+
var CssError = class extends TochiResError {
|
|
112
|
+
constructor(message, options = {}) {
|
|
113
|
+
super(options.code ?? ErrorCode.CssParse, message, options);
|
|
114
|
+
this.name = "CssError";
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/errors/ipc.ts
|
|
119
|
+
/** An IPC transport, protocol, authentication or timeout failure. */
|
|
120
|
+
var IpcError = class extends TochiResError {
|
|
121
|
+
constructor(message, options = {}) {
|
|
122
|
+
super(options.code ?? ErrorCode.IpcTransport, message, options);
|
|
123
|
+
this.name = "IpcError";
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/errors/native.ts
|
|
128
|
+
/** A native module or method was missing, or a native call failed. */
|
|
129
|
+
var NativeError = class extends TochiResError {
|
|
130
|
+
constructor(message, options = {}) {
|
|
131
|
+
super(options.code ?? ErrorCode.NativeCallFailed, message, options);
|
|
132
|
+
this.name = "NativeError";
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/errors/package.ts
|
|
137
|
+
/** A packaging, signing or notarization step failed. */
|
|
138
|
+
var PackageError = class extends TochiResError {
|
|
139
|
+
constructor(message, options = {}) {
|
|
140
|
+
super(options.code ?? ErrorCode.PackageFailed, message, options);
|
|
141
|
+
this.name = "PackageError";
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/errors/path.ts
|
|
146
|
+
/** A path was malformed or violated the relative-path rule. */
|
|
147
|
+
var PathError = class extends TochiResError {
|
|
148
|
+
constructor(message, options = {}) {
|
|
149
|
+
super(options.code ?? ErrorCode.PathInvalid, message, options);
|
|
150
|
+
this.name = "PathError";
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
//#endregion
|
|
154
|
+
//#region src/errors/settings.ts
|
|
155
|
+
/** Settings text could not be parsed or failed validation. */
|
|
156
|
+
var SettingsError = class extends TochiResError {
|
|
157
|
+
constructor(message, options = {}) {
|
|
158
|
+
super(options.code ?? ErrorCode.SettingsInvalid, message, options);
|
|
159
|
+
this.name = "SettingsError";
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
//#endregion
|
|
163
|
+
//#region src/errors/validation.ts
|
|
164
|
+
/** A payload, schema or argument failed validation. */
|
|
165
|
+
var ValidationError = class extends TochiResError {
|
|
166
|
+
constructor(message, options = {}) {
|
|
167
|
+
super(options.code ?? ErrorCode.ValidationFailed, message, options);
|
|
168
|
+
this.name = "ValidationError";
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/errors/index.ts
|
|
173
|
+
const CLASS_BY_CATEGORY = {
|
|
174
|
+
config: ConfigError,
|
|
175
|
+
validation: ValidationError,
|
|
176
|
+
api: ApiError,
|
|
177
|
+
ipc: IpcError,
|
|
178
|
+
codegen: CodegenError,
|
|
179
|
+
css: CssError,
|
|
180
|
+
native: NativeError,
|
|
181
|
+
build: BuildError,
|
|
182
|
+
package: PackageError,
|
|
183
|
+
settings: SettingsError,
|
|
184
|
+
path: PathError
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* The domain error class responsible for a code, or `undefined` for generic
|
|
188
|
+
* codes (which use {@link TochiResError} directly).
|
|
189
|
+
*/
|
|
190
|
+
function errorClassFor(code) {
|
|
191
|
+
const category = categoryOf(code);
|
|
192
|
+
return category === "general" ? void 0 : CLASS_BY_CATEGORY[category];
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/serialize.ts
|
|
196
|
+
/** Serialize any thrown value into a {@link SerializedError}. */
|
|
197
|
+
function serializeError(value) {
|
|
198
|
+
if (value instanceof TochiResError) return value.toJSON();
|
|
199
|
+
if (value instanceof Error) {
|
|
200
|
+
const json = {
|
|
201
|
+
name: value.name || "Error",
|
|
202
|
+
code: ErrorCode.Unknown,
|
|
203
|
+
category: "general",
|
|
204
|
+
message: value.message
|
|
205
|
+
};
|
|
206
|
+
if (value.stack) json.stack = value.stack;
|
|
207
|
+
return json;
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
name: "Error",
|
|
211
|
+
code: ErrorCode.Unknown,
|
|
212
|
+
category: "general",
|
|
213
|
+
message: stringifyUnknown(value)
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/** Whether a value looks like a {@link SerializedError}. */
|
|
217
|
+
function isSerializedError(value) {
|
|
218
|
+
if (typeof value !== "object" || value === null) return false;
|
|
219
|
+
const record = value;
|
|
220
|
+
return isErrorCode(record.code) && typeof record.message === "string";
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Rebuild a {@link TochiResError} (with the right domain subclass) from a
|
|
224
|
+
* {@link SerializedError}, preserving the cause chain.
|
|
225
|
+
*/
|
|
226
|
+
function deserializeError(value) {
|
|
227
|
+
const record = typeof value === "object" && value !== null ? value : {};
|
|
228
|
+
const code = isErrorCode(record.code) ? record.code : ErrorCode.Unknown;
|
|
229
|
+
const message = typeof record.message === "string" ? record.message : "Unknown error";
|
|
230
|
+
const ErrorClass = errorClassFor(code);
|
|
231
|
+
const context = record.context;
|
|
232
|
+
const error = ErrorClass ? new ErrorClass(message, {
|
|
233
|
+
code,
|
|
234
|
+
context
|
|
235
|
+
}) : new TochiResError(code, message, context ? { context } : {});
|
|
236
|
+
if (record.stack) error.stack = record.stack;
|
|
237
|
+
if (record.cause) error.cause = deserializeError(record.cause);
|
|
238
|
+
return error;
|
|
239
|
+
}
|
|
240
|
+
function stringifyUnknown(value) {
|
|
241
|
+
if (typeof value === "string") return value;
|
|
242
|
+
try {
|
|
243
|
+
return JSON.stringify(value) ?? String(value);
|
|
244
|
+
} catch {
|
|
245
|
+
return String(value);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
//#endregion
|
|
249
|
+
export { serializeCause as _, ValidationError as a, PackageError as c, CssError as d, ConfigError as f, TochiResError as g, ApiError as h, errorClassFor as i, NativeError as l, BuildError as m, isSerializedError as n, SettingsError as o, CodegenError as p, serializeError as r, PathError as s, deserializeError as t, IpcError as u };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { n as ErrorCategory, r as ErrorCode } from "./codes-CCNEPVSz.js";
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* The wire representation of an error. Produced by {@link serializeError} and
|
|
5
|
+
* accepted by `deserializeError`; safe to embed in a JSON-RPC error object.
|
|
6
|
+
*/
|
|
7
|
+
interface SerializedError {
|
|
8
|
+
/** The error class name, e.g. `ConfigError`. */
|
|
9
|
+
name: string;
|
|
10
|
+
/** Stable {@link ErrorCode}. */
|
|
11
|
+
code: ErrorCode;
|
|
12
|
+
/** Coarse category derived from the code. */
|
|
13
|
+
category: ErrorCategory;
|
|
14
|
+
/** Human-readable message. */
|
|
15
|
+
message: string;
|
|
16
|
+
/** Stack trace, when available. */
|
|
17
|
+
stack?: string;
|
|
18
|
+
/** Structured, JSON-safe context for logging/telemetry. */
|
|
19
|
+
context?: Record<string, unknown>;
|
|
20
|
+
/** Serialized cause chain. */
|
|
21
|
+
cause?: SerializedError;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/base.d.ts
|
|
25
|
+
/** Options accepted by every {@link TochiResError}. */
|
|
26
|
+
interface TochiResErrorOptions {
|
|
27
|
+
/** Underlying error/value that caused this one. */
|
|
28
|
+
cause?: unknown;
|
|
29
|
+
/** Structured, JSON-safe context for logging and telemetry. */
|
|
30
|
+
context?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Base class for every typed error in this package.
|
|
34
|
+
*
|
|
35
|
+
* Carries a stable {@link ErrorCode} (mirrored in C#), a derived
|
|
36
|
+
* {@link ErrorCategory}, optional structured context and an optional cause
|
|
37
|
+
* chain, and serializes to a {@link SerializedError} that survives JSON-RPC.
|
|
38
|
+
*/
|
|
39
|
+
declare class TochiResError extends Error {
|
|
40
|
+
/** Stable code — part of the public contract. */
|
|
41
|
+
readonly code: ErrorCode;
|
|
42
|
+
/** Coarse category derived from {@link code}. */
|
|
43
|
+
readonly category: ErrorCategory;
|
|
44
|
+
/** Structured, JSON-safe context. */
|
|
45
|
+
readonly context?: Record<string, unknown>;
|
|
46
|
+
/** Underlying cause, if any. */
|
|
47
|
+
readonly cause?: unknown;
|
|
48
|
+
constructor(code: ErrorCode, message: string, options?: TochiResErrorOptions);
|
|
49
|
+
/** Serialize this error (and its cause chain) to a wire-safe object. */
|
|
50
|
+
toJSON(): SerializedError;
|
|
51
|
+
}
|
|
52
|
+
/** Serialize any value used as a `cause` into a {@link SerializedError}. */
|
|
53
|
+
declare function serializeCause(value: unknown): SerializedError | undefined;
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/serialize.d.ts
|
|
56
|
+
/** Serialize any thrown value into a {@link SerializedError}. */
|
|
57
|
+
declare function serializeError(value: unknown): SerializedError;
|
|
58
|
+
/** Whether a value looks like a {@link SerializedError}. */
|
|
59
|
+
declare function isSerializedError(value: unknown): value is SerializedError;
|
|
60
|
+
/**
|
|
61
|
+
* Rebuild a {@link TochiResError} (with the right domain subclass) from a
|
|
62
|
+
* {@link SerializedError}, preserving the cause chain.
|
|
63
|
+
*/
|
|
64
|
+
declare function deserializeError(value: unknown): TochiResError;
|
|
65
|
+
//#endregion
|
|
66
|
+
export { TochiResErrorOptions as a, TochiResError as i, isSerializedError as n, serializeCause as o, serializeError as r, SerializedError as s, deserializeError as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tochii/errors",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"description": "Shared typed errors and stable error codes used in official tochiResources proejcts.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "T0chi",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/tochiResources/errors.git"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsdown --config-loader unrun",
|
|
14
|
+
"format": "dbx fmt",
|
|
15
|
+
"lint": "dbx lint --fix",
|
|
16
|
+
"check": "dbx check",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"typecheck": "tsc -p tsconfig.build.json --noEmit",
|
|
19
|
+
"dbx": "dbx",
|
|
20
|
+
"commitlint": "commitlint",
|
|
21
|
+
"prepare": "husky"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@commitlint/cli": "^21.2.2",
|
|
25
|
+
"@commitlint/config-conventional": "^21.2.2",
|
|
26
|
+
"@deltabox/toolchain": "^1.11.3",
|
|
27
|
+
"@types/node": "^22.10.2",
|
|
28
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
29
|
+
"husky": "^9.1.7",
|
|
30
|
+
"tsdown": "^0.23.0",
|
|
31
|
+
"tsx": "^4.23.13",
|
|
32
|
+
"typescript": "^6.0.3",
|
|
33
|
+
"unrun": "^0.3.1",
|
|
34
|
+
"vite": "^8.3.0",
|
|
35
|
+
"vite-plus": "^1.2.0",
|
|
36
|
+
"vitest": "^5.0.0"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"packageManager": "yarn@4.17.1",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22.5.0"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"dist",
|
|
47
|
+
"csharp"
|
|
48
|
+
],
|
|
49
|
+
"types": "./dist/index.d.ts",
|
|
50
|
+
"exports": {
|
|
51
|
+
".": "./dist/index.js",
|
|
52
|
+
"./codes": "./dist/codes.js",
|
|
53
|
+
"./serialize": "./dist/serialize.js",
|
|
54
|
+
"./package.json": "./package.json"
|
|
55
|
+
}
|
|
6
56
|
}
|