Skip to content

Adds error options to AppError class#191

Merged
w3nl merged 1 commit intomainfrom
feature/error-options
Oct 16, 2025
Merged

Adds error options to AppError class#191
w3nl merged 1 commit intomainfrom
feature/error-options

Conversation

@w3nl
Copy link
Copy Markdown
Contributor

@w3nl w3nl commented Oct 16, 2025

Extends the AppError class to accept an options object, aligning with the native Error constructor (ES2022) for enhanced error handling capabilities.

This enhancement allows for specifying a 'cause' property, enabling the chaining of errors and providing more contextual information for debugging and error analysis.

Updates related unit tests to reflect the added 'options' property.

Summary by CodeRabbit

  • New Features

    • AppError constructor accepts an options parameter, enabling error cause and related metadata.
  • Documentation

    • Docs updated to list the new options field for error payloads and link to the standard Error reference.
  • Tests

    • Test cases updated to validate the presence and structure of the new options field on errors.

@w3nl w3nl requested a review from Copilot October 16, 2025 19:04
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 16, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

The AppError constructor now accepts an optional ErrorOptions parameter and forwards it to the native Error via super(message, options). Documentation (README) was updated to list the new options payload field and tests were adjusted to assert an options property on AppError instances.

Changes

Cohort / File(s) Change Summary
Documentation
README.md
Added options field to payload properties with ErrorOptions type and linked MDN Error reference.
Core Implementation
src/app-error.js
Added ErrorOptions typedef (including cause), updated AppError constructor to accept options and pass them to super(message, opts), and documented error.options in JSDoc.
Test Coverage
src/__tests__/app-error.test.js
Updated tests to expect an options property on AppError object literals (first two cases options: null, third case includes nested cause).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller
  participant AppError
  participant NativeError as Error

  Caller->>AppError: new AppError(message, options?)
  Note right of AppError: normalize options (null -> undefined)
  AppError->>NativeError: super(message, optionsOrUndefined)
  NativeError-->>AppError: constructed Error (with .cause if provided)
  AppError-->>Caller: returns AppError instance (includes .message, .options)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🐰
I hopped through code with curious eyes,
Carried causes where the mystery lies.
Options tucked in each error's name,
Now every fault has a little flame.
🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately describes the primary change—adding support for error options to the AppError class—providing clear context for reviewers.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/error-options

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 18443c6 and 2af3dd8.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • README.md (1 hunks)
  • src/__tests__/app-error.test.js (3 hunks)
  • src/app-error.js (2 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
README.md

29-29: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)


29-29: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (1)
src/app-error.js (1)

35-37: Null coalescing correctly handles invalid options values.

The implementation correctly coalesces null to undefined before passing to super(), preventing potential TypeErrors in ES2022 environments where ToObject(null) is invalid.

However, verify that the JSDoc on line 33 accurately reflects this behavior. Consider updating it to explicitly document that null is accepted and handled:

-     * @param {ErrorOptions=} error.options
+     * @param {ErrorOptions|null=} error.options

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds support for ES2022 Error options to AppError to enable error chaining via cause, with corresponding test and README updates.

  • AppError constructor now accepts an options property and forwards it to super(message, options).
  • Introduces JSDoc typedef for ErrorOptions and updates constructor JSDoc.
  • Updates unit tests and README to include the options parameter.

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/app-error.js Adds ErrorOptions typedef and forwards options to the Error constructor.
src/tests/app-error.unit.js Adds options in test cases, including a cause example.
README.md Documents the new options parameter and links to MDN.

src/app-error.js Outdated
constructor ({ value = null, type = null, message, me = null }) {
super(message)
constructor ({ value = null, type = null, message, me = null, options }) {
super(message, options)
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing options: null (as done in the updated tests) to super(message, options) can throw a TypeError in environments that implement ES2022 Error options because ToObject(null) is invalid. Coalesce null to undefined before forwarding to super to maintain compatibility: e.g., compute const opts = options == null ? undefined : options and call super(message, opts).

Suggested change
super(message, options)
const opts = options == null ? undefined : options
super(message, opts)

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +31
me: null,
options: null
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

options: null is not a valid ErrorOptions per the ES2022 Error constructor and may cause a TypeError in modern runtimes; use undefined or omit the property instead. Replace with options: undefined, or remove the options field entirely.

Suggested change
me: null,
options: null
me: null

Copilot uses AI. Check for mistakes.
Comment on lines +72 to 76
me: AppError,
options: { cause: new Error('Root cause') }
})

assert.deepEqual(error instanceof AppError, true)
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test does not assert that the cause is propagated, which is the core behavior introduced by this PR. Add an assertion such as assert.equal(error.cause?.message, 'Root cause') and, in the tests where options is omitted/undefined, assert that error.cause is undefined.

Copilot generated this review using guidance from repository custom instructions.
* value (type: mixed)
* type (String|Array|Object|Number|Boolean|Date|...)
* me (current method, no validation on the value)
* options (ErrorOptions, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error)
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarify that options must be an object (not null) and that when provided with a cause, it will be available on error.cause. Consider adding a short example: new AppError({ message: '...', options: { cause: new Error('reason') } }) -> error.cause.message === 'reason'.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/__tests__/app-error.unit.js (1)

67-86: Add assertion to verify error.cause is set correctly.

The test creates an AppError with options: { cause: new Error('Root cause') } but doesn't verify that the cause was actually set on the error instance. This means the primary functionality of the new feature (error chaining) is not being tested.

Add an assertion after line 85 to verify the cause:

     assert.deepEqual(error.me, AppError)
+    assert.deepEqual(error.cause instanceof Error, true)
+    assert.deepEqual(error.cause.message, 'Root cause')
   })

This ensures that the ES2022 ErrorOptions are properly propagated to the native Error constructor.

🧹 Nitpick comments (2)
README.md (1)

64-92: Consider adding an example demonstrating the new options parameter.

The documentation now mentions the options parameter, but the example usage doesn't demonstrate how to use it with error chaining (the primary use case for this feature).

Consider adding an example that shows error chaining with cause:

doSomethingWrong () {
    try {
        // Some operation that might fail
    } catch (originalError) {
        throw new NotFoundError({
            value: 'test',
            type: String,
            message: 'Example text',
            me: this.constructor,
            options: { cause: originalError }
        });
    }
}

This would help users understand the practical application of the new feature.

src/__tests__/app-error.unit.js (1)

25-44: Consider adding a negative test for null options.

While this test verifies that passing options: null doesn't break the constructor, it doesn't explicitly assert that error.cause is undefined in this case.

For completeness, you could add an assertion:

     assert.deepEqual(error.me, null)
+    assert.deepEqual(error.cause, undefined)
   })

This would document the expected behavior when options is explicitly null.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 012f8f8 and 138e740.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • README.md (1 hunks)
  • src/__tests__/app-error.unit.js (3 hunks)
  • src/app-error.js (2 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
README.md

29-29: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)


29-29: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
src/app-error.js (2)

7-11: LGTM! Proper ES2022 ErrorOptions typedef.

The typedef correctly documents the ErrorOptions interface with an optional cause property, aligning with the ES2022 Error constructor specification.


35-36: LGTM! Options correctly passed to native Error constructor.

The implementation properly:

  1. Accepts options in the destructured parameter (will be undefined if not provided)
  2. Passes it to the super(message, options) call, enabling ES2022 error chaining

The native Error constructor will handle storing the cause on the instance, so it's correctly accessible via error.cause without needing to explicitly store it in setValues or include it in the values getter.

* value (type: mixed)
* type (String|Array|Object|Number|Boolean|Date|...)
* me (current method, no validation on the value)
* options (ErrorOptions, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix markdown formatting issues.

The line has two formatting issues flagged by markdownlint:

  1. List indentation is incorrect (should be 0 spaces, currently 1)
  2. Bare URL should be formatted as a proper link

Apply this diff to fix the formatting:

- * options (ErrorOptions, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error)
+* options (ErrorOptions, see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error>)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* options (ErrorOptions, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error)
* options (ErrorOptions, see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error>)
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

29-29: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)


29-29: Bare URL used

(MD034, no-bare-urls)

🤖 Prompt for AI Agents
In README.md around line 29, the list item has incorrect indentation and a bare
URL; fix by removing the leading space so the asterisk is at column 0 and
replace the raw URL with a proper markdown link (e.g. ErrorOptions linking to
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error)
so the line reads a properly indented list item with a formatted link.

@w3nl w3nl requested a review from Copilot October 16, 2025 19:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 3 out of 15 changed files in this pull request and generated 3 comments.

Comment on lines +7 to +12
/**
* Options for the native Error constructor (ES2022).
* @typedef {object} ErrorOptions
* @property {unknown} [cause]
*/

Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This local JSDoc typedef name 'ErrorOptions' conflicts with the global ES2022 'ErrorOptions' type in TypeScript/checkJs environments, causing duplicate identifier errors. Remove this typedef and reference the built-in 'ErrorOptions' in JSDoc, or rename it (e.g., 'AppErrorOptions') and update the constructor JSDoc to use that new name.

Copilot generated this review using guidance from repository custom instructions.
* @param {object=} error.type
* @param {string} error.message
* @param {object=} error.me
* @param {ErrorOptions=} error.options
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSDoc states 'options' is of type ErrorOptions (object), but tests pass null. Clarify the accepted types to avoid confusion and checkJs complaints. Suggest updating to: '@param {ErrorOptions|undefined|null=} error.options'.

Suggested change
* @param {ErrorOptions=} error.options
* @param {ErrorOptions|undefined|null=} error.options

Copilot uses AI. Check for mistakes.
Comment on lines 69 to 74
value: 'test',
type: String,
message: 'Example text',
me: AppError
me: AppError,
options: { cause: new Error('Root cause') }
})
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new behavior (options.cause propagation) isn't asserted. Add expectations to verify that 'error.cause' is set when provided and absent otherwise, e.g., 'assert.equal(error.cause instanceof Error, true)' and 'assert.equal(error.cause.message, 'Root cause')' for this case, and 'assert.equal(error.cause, undefined)' in the null/undefined options cases.

Copilot generated this review using guidance from repository custom instructions.
Extends the AppError class to accept an options object, aligning with the native Error constructor (ES2022) for enhanced error handling capabilities.

This enhancement allows for specifying a 'cause' property, enabling the chaining of errors and providing more contextual information for debugging and error analysis.

Updates related unit tests to reflect the added 'options' property.
@w3nl w3nl force-pushed the feature/error-options branch from 18443c6 to 2af3dd8 Compare October 16, 2025 19:19
@w3nl w3nl requested a review from Copilot October 16, 2025 19:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 3 out of 15 changed files in this pull request and generated 1 comment.

Comment on lines +36 to +37
const opts = options == null ? undefined : options
super(message, opts)
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Avoid loose equality and the temporary variable; use nullish coalescing inline. For example: super(message, options ?? undefined). This keeps the intent (treat null/undefined as absent) while remaining concise and avoiding ==.

Suggested change
const opts = options == null ? undefined : options
super(message, opts)
super(message, options ?? undefined)

Copilot uses AI. Check for mistakes.
@w3nl w3nl merged commit 4a9921a into main Oct 16, 2025
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants