Ejecuto la aplicación Angular 12 y quiero lograr un comportamiento para crear un controlador de errores personalizado para manejar errores globalmente.
Cada vez que recibo una notificación de error del backend, la suscribo en ToolService usando this.notificationService.registerToServerCalls(......) . Desde aquí, lanzo la CustomException que debería ir a CustomErrorHandler para manejar el error. Pero, una vez que se lanza la CustomException, el código no va al CustomErrorHandler
herramienta.servicio.ts
@Injectable() export class ToolService { constructor( private notificationService: NotificationService, @Inject(ErrorHandler) private errorHandler: CustomErrorHandler) { this.errorHandler.onUnhandledException$.subscribe({ next: (error: ErrorDetail[]) => { this.dialogService.open(error); } }); } this.notificationRService.registerToServerCalls<ErrorDetail[]>('Error', (errorDetail: ErrorDetail[]) => { this.onError.next(errorDetail); throw new CustomException(errorDetail); });notificación.servicio.ts
public registerToServerCalls<T>(clientMethod: string, callback: (data: T) => void): void { this.hubConnection.on(clientMethod, callback); }custom-exception.model.ts
export class CustomException extends Error { error: ErrorDetail[]; constructor(error?: ErrorDetail[]) { super(); this.error = error; } }controlador de errores personalizado.ts
@Injectable() export class CustomErrorHandler implements ErrorHandler { private onUnhandledException = new Subject(); onUnhandledException$ = this.onUnhandledException.asObservable(); isErrorHandled = false; /** * Override the base class error handler to handle the error. */ handleError(errorObj) { if (this.isErrorHandled) { return; } errorObj = errorObj.rejection ? errorObj.rejection : errorObj; // .rejection is required in case of promise rejections. let errorDetails: ErrorDetail[]; errorDetails = errorObj.error; this.onUnhandledException.next(errorDetails); this.isErrorHandled = true; } }Hay una explicación muy simple para esto, aunque no estoy seguro de por qué sucede. Tuve un poco el mismo problema recientemente
El problema es que Angular usa una instancia diferente de CustomErrorHandler que la que inyecta en su servicio.
Esto podría resolverse usando lo siguiente en su controlador de errores y servicios, pero dudo mucho que eso funcione.
@Injectable({ providedIn: 'root' })En mi caso utilicé un segundo servicio. Algo como esto:
export class ErrorMessageService { private onUnhandledException = new Subject(); onUnhandledException$ = this.onUnhandledException.asObservable(); setMessage(message: string){ onUnhandledException.next(message); } } export class CustomErrorHandler implements ErrorHandler { constructor(private errorMessageService: ErrorMessageService) handleError(errorObj) { this.errorMessageService.setMessage(...) ... ... } } export class ToolService { constructor( private notificationService: NotificationService, private errorMessageService: ErrorMessageService) { this.errorMessageService.onUnhandledException$.subscribe({ next: (error: ErrorDetail[]) => { this.dialogService.open(error); } }); } }Alternativamente, puede fusionar ErrorMessageService y Toolservice e inyectar toolservice en su controlador de errores.