فهرست منبع

[OError] getFullInfo returns the error context of nested causes (#14)

* [OError] add getFullInfoIncludeCause for retrieving nested cause info

* Revert "[OError] add getFullInfoIncludeCause for retrieving nested cause info"

This reverts commit 4c7517255a0f37ba94223e559a3926f19bab618d

* [OError] getFullInfo returns the error context of nested causes

* [OError] getFullInfo flip sequence of merging, add test case for it
Jakob Ackermann 5 سال پیش
والد
کامیت
a5e5d9b1cd
4فایلهای تغییر یافته به همراه38 افزوده شده و 10 حذف شده
  1. 2 2
      libraries/o-error/README.md
  2. 2 2
      libraries/o-error/index.d.ts
  3. 4 2
      libraries/o-error/index.js
  4. 30 4
      libraries/o-error/test/o-error-util.test.js

+ 2 - 2
libraries/o-error/README.md

@@ -442,7 +442,7 @@ async function cleanup() {
 <a name="OError.getFullInfo"></a>
 <a name="OError.getFullInfo"></a>
 
 
 ### OError.getFullInfo(error) ⇒ <code>Object</code>
 ### OError.getFullInfo(error) ⇒ <code>Object</code>
-The merged info from any `tag`s on the given error.
+The merged info from any `tag`s and causes on the given error.
 
 
 If an info property is repeated, the last one wins.
 If an info property is repeated, the last one wins.
 
 
@@ -450,7 +450,7 @@ If an info property is repeated, the last one wins.
 
 
 | Param | Type | Description |
 | Param | Type | Description |
 | --- | --- | --- |
 | --- | --- | --- |
-| error | <code>Error</code> \| <code>null</code> \| <code>undefined</code> | any errror (may or may not be an `OError`) |
+| error | <code>Error</code> \| <code>null</code> \| <code>undefined</code> | any error (may or may not be an `OError`) |
 
 
 <a name="OError.getFullStack"></a>
 <a name="OError.getFullStack"></a>
 
 

+ 2 - 2
libraries/o-error/index.d.ts

@@ -63,11 +63,11 @@ declare namespace OError {
      */
      */
     export function tag(error: Error, message?: string, info?: any): Error;
     export function tag(error: Error, message?: string, info?: any): Error;
     /**
     /**
-     * The merged info from any `tag`s on the given error.
+     * The merged info from any `tag`s and causes on the given error.
      *
      *
      * If an info property is repeated, the last one wins.
      * If an info property is repeated, the last one wins.
      *
      *
-     * @param {Error | null | undefined} error any errror (may or may not be an `OError`)
+     * @param {Error | null | undefined} error any error (may or may not be an `OError`)
      * @return {Object}
      * @return {Object}
      */
      */
     export function getFullInfo(error: Error): any;
     export function getFullInfo(error: Error): any;

+ 4 - 2
libraries/o-error/index.js

@@ -98,11 +98,11 @@ class OError extends Error {
   }
   }
 
 
   /**
   /**
-   * The merged info from any `tag`s on the given error.
+   * The merged info from any `tag`s and causes on the given error.
    *
    *
    * If an info property is repeated, the last one wins.
    * If an info property is repeated, the last one wins.
    *
    *
-   * @param {Error | null | undefined} error any errror (may or may not be an `OError`)
+   * @param {Error | null | undefined} error any error (may or may not be an `OError`)
    * @return {Object}
    * @return {Object}
    */
    */
   static getFullInfo(error) {
   static getFullInfo(error) {
@@ -112,6 +112,8 @@ class OError extends Error {
 
 
     const oError = /** @type{OError} */ (error)
     const oError = /** @type{OError} */ (error)
 
 
+    if (oError.cause) Object.assign(info, OError.getFullInfo(oError.cause))
+
     if (typeof oError.info === 'object') Object.assign(info, oError.info)
     if (typeof oError.info === 'object') Object.assign(info, oError.info)
 
 
     if (oError._oErrorTags) {
     if (oError._oErrorTags) {

+ 30 - 4
libraries/o-error/test/o-error-util.test.js

@@ -282,12 +282,38 @@ describe('OError.getFullInfo', function () {
     })
     })
   })
   })
 
 
-  it('does not merge info from a cause', function () {
+  it('merges info from a cause', function () {
     const err1 = new Error('foo')
     const err1 = new Error('foo')
     const err2 = new Error('bar')
     const err2 = new Error('bar')
     err1.cause = err2
     err1.cause = err2
     err2.info = { userId: 123 }
     err2.info = { userId: 123 }
-    expect(OError.getFullInfo(err1)).to.deep.equal({})
+    expect(OError.getFullInfo(err1)).to.deep.equal({ userId: 123 })
+  })
+
+  it('merges info from a nested cause', function () {
+    const err1 = new Error('foo')
+    const err2 = new Error('bar')
+    const err3 = new Error('baz')
+    err1.cause = err2
+    err2.info = { userId: 123 }
+    err2.cause = err3
+    err3.info = { foo: 42 }
+    expect(OError.getFullInfo(err1)).to.deep.equal({
+      userId: 123,
+      foo: 42,
+    })
+  })
+
+  it('merges info from cause with duplicate keys', function () {
+    const err1 = new Error('foo')
+    const err2 = new Error('bar')
+    err1.info = { userId: 42, foo: 1337 }
+    err1.cause = err2
+    err2.info = { userId: 1 }
+    expect(OError.getFullInfo(err1)).to.deep.equal({
+      userId: 42,
+      foo: 1337,
+    })
   })
   })
 
 
   it('merges info from tags with duplicate keys', function () {
   it('merges info from tags with duplicate keys', function () {
@@ -371,8 +397,8 @@ describe('OError.getFullStack', function () {
         '    TaggedError: failed to foo',
         '    TaggedError: failed to foo',
       ])
       ])
 
 
-      // The info from the wrapped cause should not leak out.
-      expect(OError.getFullInfo(error)).to.eql({ bat: 1 })
+      // The info from the wrapped cause should be picked up for logging.
+      expect(OError.getFullInfo(error)).to.eql({ bat: 1, foo: 1 })
 
 
       // But it should still be recorded.
       // But it should still be recorded.
       expect(OError.getFullInfo(error.cause)).to.eql({ foo: 1 })
       expect(OError.getFullInfo(error.cause)).to.eql({ foo: 1 })