Как ограничить область действия ErrorHandler? - PullRequest
6 голосов
/ 03 мая 2019

У меня есть глобальный обработчик ошибок, определенный как таковой (упрощенная / проприетарная информация очищена):

export class ErrorsHandler extends CommonBase implements ErrorHandler {
  constructor(protected loggingService: LoggingService,
              private coreService: CoreService {

    super(loggingService);
  }

  handleError(error: Error) {
    if (error && error.stack && (error.stack.indexOf(Constants.PACKAGE_NAME) >= 0)) {
      this.logSystemError(error, true);
      this.coreService.showSystemError(error, this.owner);
    }
    else {
      // Rethrow all other errors.
      throw error;
    }
  }

И в моем модуле (и только в моем модуле) он зарегистрирован как провайдер как таковой:

export function errorHandlerFactory(loggingService: LoggingService, coreService: CoreService) {
  return new ErrorsHandler(loggingService, coreService);
}

providers: [
    { provide: ErrorHandler, useFactory: errorHandlerFactory, deps: [LoggingService, CoreService] }
]

Мой модуль используется другими, и вместе мы составляем одно большое приложение. Моя проблема заключается в том, что ВСЕ ошибки скрипта обнаруживаются, хотя я пытаюсь отфильтровать те, которые имеют отношение только к моему модулю / пакету, потому что фильтрация выполняется в handleError(). И даже несмотря на то, что я перебрасываю ошибки, которые мне не нужны (в else выше), разработчики других модулей / пакетов жалуются, что я глобально ловлю все, и переброшенные ошибки, которые они получают, уже теряют определенный контекст / информацию.

Таким образом, вопрос в том, можно ли каким-то образом ограничить область действия моего обработчика ошибок, чтобы перехватывать и обрабатывать ТОЛЬКО ошибки скрипта, происходящие из моего модуля / пакета (при этом полностью игнорируя все другие ошибки скрипта в приложении)?

После долгих поисков, единственная альтернатива, которую я могу придумать, - это поставить try/catch везде, чего я бы хотел избежать, если это вообще возможно.

Ответы [ 2 ]

3 голосов
/ 14 мая 2019

Вы можете попробовать создать службу - ErrorService, чтобы поделиться context, а затем throw ошибка от global error handler.Затем вы можете catch ошибка от требуемого Component.

PFB шаги:

  1. Создайте службу ошибок следующим образом:

    @Injectable({
        providedIn: 'root'
    })
    export class ErrorService {
        constructor() {}
    
        private error = new BehaviorSubject(new Error());
        error_message = this.error.asObservable();
    
        changeMessage(e: Error) {
            this.error.next(e);
        }
    }
    
  2. throw ошибка отhandleError метод в ErrorHandler.PFB фрагмент:

    handleError(error: Error) {
         if (error && error.stack &&(error.stack.indexOf(Constants.PACKAGE_NAME) >= 0)) 
         {
              this.logSystemError(error, true);
              this.coreService.showSystemError(error, this.owner);
         }
         else {
              //`errorService` is the `instance` for `ErrorService Component` 
              //imported in the defined `ErrorHandler`
              this.errorService.changeMessage(error);
              // Rethrow all other errors.
              throw error;
         }
      }
    
  3. Используйте try-catch, чтобы поймать ошибку в вашем Component.Используйте error_message из ErrorService для того же.

1 голос
/ 14 мая 2019

Я не знаю, что делает CommonBase, и поэтому я не уверен, что это выполнимый ответ, но одна вещь, которую вы могли бы сделать, это немного изменить ErrorsHandler.Если вы измените свою структуру и унаследуете ядро ​​ErrorHandler вместо реализации его интерфейса, вы можете получить что-то вроде этого:

import { Injectable, ErrorHandler } from '@angular/core';

@Injectable()
export class ErrorsHandler extends ErrorHandler {

  constructor() {
    super();
  }

  handleError(error: any): void {
    if(error && error.stack && error.stack.indexOf("MyModule") >= 0) {
      console.log(`Uff, that was close. Got ${error}`);
      return;
    }
    super.handleError(error);
  }
}

Я подумал, что это даст вам гораздо больше надежности и будет распространять ошибкиправильно.Повторная выдача ошибки как-то не работает должным образом, но я не на 100% уверен в точной причине.

Надеюсь, это поможет!

...