fix(core): correctly handle `null` or `undefined` in `ErrorHandler#handleError()` (#42881)
Since `ErrorHandler#handleError()` expects an argument of type `any` it should be able to handle values such as `null` and `undefined`. Previously, it failed to handle these values, because it was trying to access properties on them. This commit fixes it by ensuring no properties are accessed on `null` or `undefined` values. NOTE: This is part of fully addressing #28106. Fixes #21252 PR Close #42881
This commit is contained in:
parent
4d86ea6471
commit
eefe1682e8
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {getDebugContext, getErrorLogger, getOriginalError} from './errors';
|
import {getDebugContext, getErrorLogger, getOriginalError} from './errors';
|
||||||
|
import {DebugContext} from './view/types';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,17 +59,17 @@ export class ErrorHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_findContext(error: any): any {
|
_findContext(error: any): DebugContext|null {
|
||||||
return error ? (getDebugContext(error) || this._findContext(getOriginalError(error))) : null;
|
return error ? (getDebugContext(error) || this._findContext(getOriginalError(error))) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_findOriginalError(error: Error): any {
|
_findOriginalError(error: any): Error|null {
|
||||||
let e = getOriginalError(error);
|
let e = error && getOriginalError(error);
|
||||||
while (e && getOriginalError(e)) {
|
while (e && getOriginalError(e)) {
|
||||||
e = getOriginalError(e);
|
e = getOriginalError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return e;
|
return e || null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ export function getOriginalError(error: Error): Error {
|
||||||
return (error as any)[ERROR_ORIGINAL_ERROR];
|
return (error as any)[ERROR_ORIGINAL_ERROR];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getErrorLogger(error: Error): (console: Console, ...values: any[]) => void {
|
export function getErrorLogger(error: unknown): (console: Console, ...values: any[]) => void {
|
||||||
return (error as any)[ERROR_LOGGER] || defaultErrorLogger;
|
return error && (error as any)[ERROR_LOGGER] || defaultErrorLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ function errorToString(error: any) {
|
||||||
const errorHandler = new ErrorHandler();
|
const errorHandler = new ErrorHandler();
|
||||||
(errorHandler as any)._console = logger as any;
|
(errorHandler as any)._console = logger as any;
|
||||||
errorHandler.handleError(error);
|
errorHandler.handleError(error);
|
||||||
return logger.res.map(line => line.join('#')).join('\n');
|
return logger.res.map(line => line.map(x => `${x}`).join('#')).join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('ErrorHandler', () => {
|
describe('ErrorHandler', () => {
|
||||||
|
@ -32,6 +32,16 @@ describe('ErrorHandler', () => {
|
||||||
expect(e).toContain('message!');
|
expect(e).toContain('message!');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should correctly handle primitive values', () => {
|
||||||
|
expect(errorToString('message')).toBe('ERROR#message');
|
||||||
|
expect(errorToString(404)).toBe('ERROR#404');
|
||||||
|
expect(errorToString(0)).toBe('ERROR#0');
|
||||||
|
expect(errorToString(true)).toBe('ERROR#true');
|
||||||
|
expect(errorToString(false)).toBe('ERROR#false');
|
||||||
|
expect(errorToString(null)).toBe('ERROR#null');
|
||||||
|
expect(errorToString(undefined)).toBe('ERROR#undefined');
|
||||||
|
});
|
||||||
|
|
||||||
describe('context', () => {
|
describe('context', () => {
|
||||||
it('should print nested context', () => {
|
it('should print nested context', () => {
|
||||||
const cause = new Error('message!');
|
const cause = new Error('message!');
|
||||||
|
|
Loading…
Reference in New Issue