@lowdefy/errors 6.2.0 → 6.2.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.
@@ -0,0 +1,65 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import readErrorCodes from './readErrorCodes.js';
16
+ // What a log may say about an error. Chat text and other inputs can hold personal information,
17
+ // and logs have their own retention and access, so a log carries no prompt, request property,
18
+ // tool input or document. An error carries them where a plain `{ err }` log would write them: a
19
+ // driver's error embeds the document it rejected, an AI SDK TypeValidationError's or
20
+ // JSONParseError's message embeds the value it rejected (the whole conversation, a tool's
21
+ // input), InvalidToolInputError, ToolCallRepairError and RetryError repeat their cause's
22
+ // message, and every stack opens with its message. So an AI SDK error is summarised by name
23
+ // and code alone, except APICallError, whose message is the provider's reply; any other error
24
+ // keeps its name, code, status code and message, cut to 500 characters, and none of its other
25
+ // fields. Causes are followed the same way, three deep.
26
+ const MESSAGE_LIMIT = 500;
27
+ const CAUSE_DEPTH = 3;
28
+ // AISDKError.isInstance reads this marker; the error classes themselves are not imported so
29
+ // any copy of the AI SDK in the app is recognised.
30
+ const aiSdkErrorMarker = Symbol.for('vercel.ai.error');
31
+ function isAiSdkError(error) {
32
+ return error[aiSdkErrorMarker] === true;
33
+ }
34
+ // An error from another realm, such as a DOMException in a VM context, fails instanceof Error.
35
+ function isError(value) {
36
+ if (value instanceof Error) return true;
37
+ return typeof value === 'object' && value !== null && typeof value.stack === 'string' && typeof value.message === 'string';
38
+ }
39
+ function truncate(text) {
40
+ if (text.length <= MESSAGE_LIMIT) return text;
41
+ return `${text.slice(0, MESSAGE_LIMIT - 1)}…`;
42
+ }
43
+ function errorSummaryForLog(error, depth = 0) {
44
+ if (!isError(error)) {
45
+ return {
46
+ name: typeof error
47
+ };
48
+ }
49
+ const summary = {
50
+ name: error.name
51
+ };
52
+ if (!isAiSdkError(error) || error.name === 'AI_APICallError') {
53
+ summary.message = truncate(String(error.message));
54
+ }
55
+ const { code, statusCode } = readErrorCodes(error);
56
+ if (code !== undefined) summary.code = code;
57
+ if (statusCode !== undefined) summary.statusCode = statusCode;
58
+ // A RetryError holds the attempt that failed last as lastError rather than as its cause.
59
+ const cause = error.lastError ?? error.cause;
60
+ if (cause !== undefined && depth < CAUSE_DEPTH) {
61
+ summary.cause = errorSummaryForLog(cause, depth + 1);
62
+ }
63
+ return summary;
64
+ }
65
+ export default errorSummaryForLog;
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@
59
59
  * shouldSuppressBuildCheck - Check ~ignoreBuildChecks in parent chain
60
60
  *
61
61
  * Error Field Utilities:
62
+ * errorSummaryForLog - {name, message, code, statusCode, cause} an error may log
62
63
  * readErrorCodes - {code, statusCode} from one error node's own fields
63
64
  * lowdefyErrorNames - Set of Lowdefy error class names
64
65
  * lowdefyErrorTypes - Lowdefy error class by name, for reviving and reshaping errors
@@ -68,6 +69,7 @@ import BlockError from './BlockError.js';
68
69
  import BuildError from './BuildError.js';
69
70
  import ConfigError from './ConfigError.js';
70
71
  import ConfigWarning from './ConfigWarning.js';
72
+ import errorSummaryForLog from './errorSummaryForLog.js';
71
73
  import errorToDisplayString from './errorToDisplayString.js';
72
74
  import LowdefyInternalError from './LowdefyInternalError.js';
73
75
  import lowdefyErrorNames from './lowdefyErrorNames.js';
@@ -82,4 +84,4 @@ import resolveErrorLocation from './resolveErrorLocation.js';
82
84
  import ServiceError from './ServiceError.js';
83
85
  import shouldSuppressBuildCheck, { VALID_CHECK_SLUGS } from './shouldSuppressBuildCheck.js';
84
86
  import UserError from './UserError.js';
85
- export { ActionError, AuthenticationError, BlockError, BuildError, ConfigError, ConfigWarning, errorToDisplayString, LowdefyInternalError, lowdefyErrorNames, lowdefyErrorTypes, OperatorError, PluginError, readErrorCodes, RequestError, resolveConfigLocation, loadAndResolveErrorLocation, resolveErrorLocation, ServiceError, shouldSuppressBuildCheck, UserError, VALID_CHECK_SLUGS };
87
+ export { ActionError, AuthenticationError, BlockError, BuildError, ConfigError, ConfigWarning, errorSummaryForLog, errorToDisplayString, LowdefyInternalError, lowdefyErrorNames, lowdefyErrorTypes, OperatorError, PluginError, readErrorCodes, RequestError, resolveConfigLocation, loadAndResolveErrorLocation, resolveErrorLocation, ServiceError, shouldSuppressBuildCheck, UserError, VALID_CHECK_SLUGS };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/errors",
3
- "version": "6.2.0",
3
+ "version": "6.2.1",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Lowdefy error classes for consistent error handling across build, server, and client",
6
6
  "homepage": "https://lowdefy.com",