diff --git a/renderers/web_core/CHANGELOG.md b/renderers/web_core/CHANGELOG.md index 4f7f5b27f..3bdaa6c7f 100644 --- a/renderers/web_core/CHANGELOG.md +++ b/renderers/web_core/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.8.5 + +- Add `V8ErrorConstructor` interface to be able to access V8-only + `captureStackTrace` method in errors. +- Removes dependency from `v0_8` to `v0_9` by duplicating the `errors.ts` file. + ## 0.8.4 - Tweak v0.8 Schema for Button and TextField to better match the spec. @@ -5,9 +11,3 @@ ## 0.8.3 - The `MarkdownRenderer` type is now async and returns a `Promise`. - -## 0.8.2 - -## 0.8.1 - -## 0.8.0 diff --git a/renderers/web_core/package.json b/renderers/web_core/package.json index 7cfb57aa4..9ad46f001 100644 --- a/renderers/web_core/package.json +++ b/renderers/web_core/package.json @@ -1,6 +1,6 @@ { "name": "@a2ui/web_core", - "version": "0.8.4", + "version": "0.8.5", "description": "A2UI Core Library", "main": "./dist/src/v0_8/index.js", "types": "./dist/src/v0_8/index.d.ts", @@ -77,7 +77,7 @@ "clean": "if-file-deleted" }, "test": { - "command": "node --test \"dist/**/*.test.js\"", + "command": "node --test dist", "dependencies": [ "build" ] diff --git a/renderers/web_core/src/v0_8/data/model-processor.ts b/renderers/web_core/src/v0_8/data/model-processor.ts index 20bcdcdf1..b5873464d 100644 --- a/renderers/web_core/src/v0_8/data/model-processor.ts +++ b/renderers/web_core/src/v0_8/data/model-processor.ts @@ -31,7 +31,7 @@ import { MessageProcessor, } from "../types/types.js"; import { A2uiMessageSchema } from "../schema/server-to-client.js"; -import { A2uiStateError, A2uiValidationError } from "../../v0_9/errors.js"; +import { A2uiStateError, A2uiValidationError } from "../errors.js"; import { isComponentArrayReference, isObject, diff --git a/renderers/web_core/src/v0_8/errors.ts b/renderers/web_core/src/v0_8/errors.ts new file mode 100644 index 000000000..8b0ef2582 --- /dev/null +++ b/renderers/web_core/src/v0_8/errors.ts @@ -0,0 +1,86 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This interface is needed for typescript to allow us to access the V8-only + * `captureStackTrace` property in Errors. + */ +interface V8ErrorConstructor extends ErrorConstructor { + captureStackTrace(targetObject: object, constructorOpt?: Function): void; +} + +/** + * Base class for all A2UI specific errors. + */ +export class A2uiError extends Error { + public readonly code: string; + + constructor(message: string, code: string = "UNKNOWN_ERROR") { + super(message); + this.name = this.constructor.name; + this.code = code; + + // Maintains proper stack trace for where our error was thrown (only available on V8) + if ((Error as V8ErrorConstructor).captureStackTrace) { + (Error as V8ErrorConstructor).captureStackTrace(this, this.constructor); + } + } +} + +/** + * Thrown when JSON validation fails or schemas are mismatched. + */ +export class A2uiValidationError extends A2uiError { + constructor( + message: string, + public readonly details?: any, + ) { + super(message, "VALIDATION_ERROR"); + } +} + +/** + * Thrown during DataModel mutations (invalid paths, type mismatches). + */ +export class A2uiDataError extends A2uiError { + constructor( + message: string, + public readonly path?: string, + ) { + super(message, "DATA_ERROR"); + } +} + +/** + * Thrown during string interpolation and function evaluation. + */ +export class A2uiExpressionError extends A2uiError { + constructor( + message: string, + public readonly expression?: string, + ) { + super(message, "EXPRESSION_ERROR"); + } +} + +/** + * Thrown for structural issues in the UI tree (missing surfaces, duplicate components). + */ +export class A2uiStateError extends A2uiError { + constructor(message: string) { + super(message, "STATE_ERROR"); + } +} diff --git a/renderers/web_core/src/v0_8/index.ts b/renderers/web_core/src/v0_8/index.ts index f9a3c22c9..05e8cd1cd 100644 --- a/renderers/web_core/src/v0_8/index.ts +++ b/renderers/web_core/src/v0_8/index.ts @@ -21,6 +21,7 @@ export * from "./styles/index.js"; export * from "./types/colors.js"; export * from "./types/primitives.js"; export * from "./types/types.js"; +export * from "./errors.js"; import A2UIClientEventMessage from "./schemas/server_to_client_with_standard_catalog.json" with { type: "json" }; diff --git a/renderers/web_core/src/v0_9/errors.ts b/renderers/web_core/src/v0_9/errors.ts index 1933281bc..8b0ef2582 100644 --- a/renderers/web_core/src/v0_9/errors.ts +++ b/renderers/web_core/src/v0_9/errors.ts @@ -14,6 +14,14 @@ * limitations under the License. */ +/** + * This interface is needed for typescript to allow us to access the V8-only + * `captureStackTrace` property in Errors. + */ +interface V8ErrorConstructor extends ErrorConstructor { + captureStackTrace(targetObject: object, constructorOpt?: Function): void; +} + /** * Base class for all A2UI specific errors. */ @@ -26,8 +34,8 @@ export class A2uiError extends Error { this.code = code; // Maintains proper stack trace for where our error was thrown (only available on V8) - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); + if ((Error as V8ErrorConstructor).captureStackTrace) { + (Error as V8ErrorConstructor).captureStackTrace(this, this.constructor); } } }