Skip to content

Commit a9a72f8

Browse files
committed
finish ErrorBoundary
1 parent 014ae41 commit a9a72f8

File tree

1 file changed

+50
-6
lines changed

1 file changed

+50
-6
lines changed

src/utils/ErrorBoundary.ts

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,69 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import {ObservableValue, BaseObservableValue} from "../observable/ObservableValue";
17+
export const ErrorValue = Symbol("ErrorBoundary:Error");
1818

1919
export class ErrorBoundary {
20+
private _error?: Error;
21+
2022
constructor(private readonly errorCallback: (Error) => void) {}
2123

22-
try<T>(callback: () => T): T | undefined;
23-
try<T>(callback: () => Promise<T>): Promise<T | undefined> | undefined {
24+
/**
25+
* Executes callback() and then runs errorCallback() on error.
26+
* This will never throw but instead return `errorValue` if an error occured.
27+
*/
28+
try<T>(callback: () => T): T | typeof ErrorValue;
29+
try<T>(callback: () => Promise<T>): Promise<T | typeof ErrorValue> | typeof ErrorValue {
2430
try {
25-
let result: T | Promise<T | undefined> = callback();
31+
let result: T | Promise<T | typeof ErrorValue> = callback();
2632
if (result instanceof Promise) {
2733
result = result.catch(err => {
34+
this._error = err;
2835
this.errorCallback(err);
29-
return undefined;
36+
return ErrorValue;
3037
});
3138
}
3239
return result;
3340
} catch (err) {
41+
this._error = err;
3442
this.errorCallback(err);
35-
return undefined;
43+
return ErrorValue;
3644
}
3745
}
46+
47+
get error(): Error | undefined {
48+
return this._error;
49+
}
3850
}
51+
52+
export function tests() {
53+
return {
54+
"catches sync error": assert => {
55+
let emitted = false;
56+
const boundary = new ErrorBoundary(() => emitted = true);
57+
const result = boundary.try(() => {
58+
throw new Error("fail!");
59+
});
60+
assert(emitted);
61+
assert.strictEqual(result, ErrorValue);
62+
},
63+
"return value of callback is forwarded": assert => {
64+
let emitted = false;
65+
const boundary = new ErrorBoundary(() => emitted = true);
66+
const result = boundary.try(() => {
67+
return "hello";
68+
});
69+
assert(!emitted);
70+
assert.strictEqual(result, "hello");
71+
},
72+
"catches async error": async assert => {
73+
let emitted = false;
74+
const boundary = new ErrorBoundary(() => emitted = true);
75+
const result = await boundary.try(async () => {
76+
throw new Error("fail!");
77+
});
78+
assert(emitted);
79+
assert.strictEqual(result, ErrorValue);
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)