Angular: Обработка ошибок - Перехватчики и модалы - PullRequest
0 голосов
/ 25 мая 2018

Я создал приложение Angular 5, которое обрабатывает ошибки при каждом звонке.Используя HttpClient, я могу перехватить ошибку, которая происходит после отправки запроса на сервер.Ошибка перехватывается в сервисном методе, который отправляет запрос в API, а затем, когда происходит ошибка, она передается компоненту для отображения хорошего модального значения с сообщением об ошибке.

Я хочуиспользуйте перехватчики для достижения того же поведения, чтобы обрабатывать все ошибки одним централизованным способом.Но я не уверен, что можно связаться с компонентом из класса перехватчика, отправить ему сообщение, чтобы он мог запустить модальный режим, как это происходит в настоящее время, или Как я могу запустить модальный напрямую из класса перехватчика.

Это моя текущая логика:

Компонент:

  ....
 export class VerificationComponent implements OnInit {
  //Use to call the modal when errors happen
  @ViewChild('modalError') displayErrorRef: ModalComponent; 

//Method send a request to the api using a service instance _myService
getNextRecord() {

    this.errorMesage = "";
    this._myService.getCandidate()
        .subscribe(candidate => {
            this.loadCandidate = candidate;
            this.userName = this.appService.getUser();
        }, error => {                
            this.errorMesage = <any>error.errorMessage;                
            this.displayErrorRef.show();
        });
   }

}
....

Служба:

.....
@Injectable()

export class MyService {

  getCandidate(): Observable<ICandidate> {
    return this._http.get(this._getCandidateUrl, this.jwt())
        .map((response: Response) => <ICandidate>response.json())            
        .catch(this.handleError);
   }


private handleError(error: Response) {        
    if (error.text())
        return Observable.throw({errorMessage:error.text(),erroStatus: error.status });
    else
        return Observable.throw('You are not authorised to get this resource');
    }
}
....

Шаблон:

 <!-- This is a child component to display the error message on the top of 
 this template -->
  .....
<app-modal #modalError>
<div class="app-modal-header">
    Error
</div>
<div class="app-modal-body">
    {{errorMesage}}
</div>
<div class="app-modal-footer">
    <button type="button" class="btn btn-default" (click)="hideModalError()">Logout</button>
    <button type="button" class="btn btn-default"(click)="tryGetNextRecord()">Try Again</button>
</div>
</app-modal>
....

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Для примера глобального обработчика ошибок, в котором используется HttpInterceptor , необходимо следующее.

  • ErrorInterceptor
  • ErrorService
  • CustomErrorModal

Поток:

app.module => регистрация перехватчика.

app.module => служба регистрации ошибок в качестве поставщика.

app.component => зарегистрировать глобальную обработку ошибок, которая показывает модальную ошибку.

YourCustomComponent => не подписываться на ошибку субъекта / наблюдаемого

Ваш главный app.component будет подпишитесь на любые обновления от службы ошибок и отобразите их соответствующим образом, используя модальную ссылку.

app.module

//other code
const interceptors = [{
    provide: HTTP_INTERCEPTORS,
    useClass: ErrorInterceptor,
    multi: true
}];

const services = [{
    ErrorService
}];

@NgModule({
    //other code
    providers: [
        interceptors,
        services
    ],
    //other code
})

error.service

@Injectable()
export class ErrorService
{
    private errors = new Subject<string[]>();

    constructor() { }

    public addErrors = (errors: string[]): void =>
        this.errors.next(errors);

    public getErrors = () =>
        this.errors.asObservable();
}

error.interceptor

@Injectable()
export class ErrorInterceptor implements HttpInterceptor
{
    constructor(private errorService: ErrorService)
    {         
    }

    intercept(
        request: HttpRequest<any>,
        next: HttpHandler): Observable<HttpEvent<any>>
    {
        return next.handle(request).do(() => { }, (response) =>
        {
            if (response instanceof HttpErrorResponse)
            {                
                if (response.status === 401)
                {
                    return;
                }                

                if (response.status === 400 &&
                    response.error)
                {
                    this.errorService.addErrors(Array.isArray(response.error) ? response.error : [response.error]);
                    return;
                }

                this.errorService.addErrors([`Your generic error message`]);
            }

            return Observable.throw(response);
        });
    }
}

app.component

export class AppComponent implements OnDestroy
{
    private ngUnsubscribe = new Subject();

    @ViewChild('modalError')
    displayErrorRef: ModalComponent; 

    constructor(private errorService: ErrorService)
    {
        this.initializeErrors();
    }    

    ngOnDestroy()
    {
        this.ngUnsubscribe.next();
        this.ngUnsubscribe.complete();
    }

    private initializeErrors()
    {
        this
            .errorService
            .getErrors()
            .pipe(takeUntil(this.ngUnsubscribe))
            .subscribe((errors) =>
            {
                //this.displayErrorRef.error = errors
                this.displayErrorRef.show();
            });
    }   
}

ngUnsubscribe предназначен для автоматического удаления подписки при уничтожении вашего основного app.component.

0 голосов
/ 25 мая 2018

Я бы порекомендовал создать ResponseInterceptor и ErrorHandlerService для перехвата неправильных ответов (500 и т. Д.) И запуска централизованной службы, которая обрабатывает ошибки.

На данный момент я считаю, что лучший способ взаимодействия служб с компонентамис наблюдаемыми.Нечто похожее на это:

// ErrorHandlerService
private errorEvent = new Subject();
public errorEvent$ = this.errorTrigger.asObservable();
public triggerError(error: any): void {
   // manipulate your error here and then:
   this.errroEvent.next(error);
}


//ResponseInterceptor
constructor(private errorHandlerService) {}
enter code here
intercept(...): ... {
   //must check if response is an error to then:
   this.errorHandlerService.triggerError(response);
}


// Your component
fetchData() {
   this.errorHandlerService.errorEvent$.subscribe((error) => {
      // here you have the error to manipulate in your component
   });
   this.anyOtherService.fetchObject().subscribe();
}

надеюсь, что это поможет с тем, что вы ищете

...