Я обрабатываю ошибки четырьмя частями ... перехватчик http для ошибок, возвращаемых сервером, глобальный обработчик ошибок, основанный на встроенном обработчике ошибок Angular. служба ошибок, которая регистрирует ошибки в серверной службе для целей поддержки и компонент диалога материалов для отображения дружественного сообщения для конечного пользователя.
Есть некоторые ошибки, при которых мы sh фиксируем ошибку код состояния и перенаправление на компонент для более удобного взаимодействия с конечным пользователем.
Один из примеров - 404. У нас есть не найденный компонент. Если состояние ошибки сервера 404, я хочу перенаправить на не найденный компонент и не отображать диалоговое окно ошибки.
Вот мой перехватчик ...
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
import { MatDialog } from '@angular/material';
import * as StackTrace from 'stacktrace-js';
import { ErrorDialogComponent } from './error-dialog.component';
import { PathLocationStrategy } from '@angular/common';
import { ErrorService } from './error.service';
import { LoggerService } from './logger.service';
import { Router } from '@angular/router';
@Injectable()
/**
* HttpErrorInterceptor to grab errors during http calls and log them
*
* @param (clientId) client id
*/
export class HttpErrorInterceptor implements HttpInterceptor {
/**
* constructor to grab errors during http calls and log them
*
* @param (dialog) MAT dialog to display to end user
* @param (errorService) error service to grab error messages
* @param (logger) logger service to post log errors to api and mantis
*/
constructor(
public dialog: MatDialog,
private errorService: ErrorService,
private logger: LoggerService,
private router: Router
) {}
/**
* Interecept to grab request, deal with it and pass it along
*
* @param (request) http request
* @param (next) send request to next http handler
*/
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
// return the next statement
return next.handle(request).pipe(
// retry the call once
retry(1),
// catch the error
catchError((error: HttpErrorResponse) => {
if (error.status === 404) {
console.log('error.status: ', error.status);
// this.router.navigate(['']);
} else {
// Message variable to hold error message
let errorMessage = '';
// Variable to hold url location of error
const url =
location instanceof PathLocationStrategy ? location.path() : '';
// server-side error
errorMessage = this.errorService.getServerMessage(error);
// get the stack trace, lets grab the last 10 stacks only
StackTrace.fromError(error).then(stackframes => {
const stackString = stackframes
.splice(0, 20)
.map(function(sf) {
return sf.toString();
})
.join();
/**
* Function to log errors to api and mantis
*
* @param (errorMessage) error message passed to function
* @param (url) url passed to function
* @param (stackString) stackString passed to function
*/
this.logger
.createErrorLog(errorMessage, url, stackString)
.subscribe(
result => {
console.log('log filed: ', result);
},
(err: any) => console.log(err)
);
});
// Check if error is undefined and open dialog with appropriate error info
if (typeof errorMessage !== 'undefined') {
this.openDialog(errorMessage);
} else {
this.openDialog('undefined');
}
// throw error
return throwError(errorMessage);
}
})
);
}
/**
* Function to open dialog to display error
*
* @param (data) error data to display
*/
openDialog(data): void {
// Constant to hold and call dialog to display error
const dialogRef = this.dialog.open(ErrorDialogComponent, {
width: '60%',
data: data
});
// Code to run after the dialog is closed
dialogRef.afterClosed().subscribe(result => {
// Redirect back to home (dashboard)?
});
}
}
Как вы можете видеть У меня есть простой, если я проверяю код состояния. Затем у меня есть вызов метода navigate, в котором я пытаюсь выполнить маршрутизацию к нулю, поскольку в модуле моего маршрутизатора не найден компонент, указанный в качестве маршрута «none».
Это перенаправление, но также отображается диалоговое сообщение об ошибке. Я не хочу, чтобы это отображалось. Диалоговое окно просто отображает сообщение об ошибке для конечного пользователя и дает ему способы связаться с нами.
Вот мой глобальный обработчик ...
import { ErrorHandler, Injectable, Injector } from '@angular/core';
import {
HttpErrorResponse,
HttpHeaders,
HttpClient
} from '@angular/common/http';
import { LocationStrategy, PathLocationStrategy } from '@angular/common';
import { throwError } from 'rxjs';
import * as StackTrace from 'stacktrace-js';
import { LoggerService } from '../core/logger.service';
import { ErrorService } from '../core/error.service';
import { MatDialog } from '@angular/material';
import { ErrorDialogComponent } from './error-dialog.component';
import { ConfigService } from '../app-config.service';
@Injectable({
providedIn: 'root'
})
/**
* GlobalErrorHandler to grab errors and log them
*/
export class GlobalErrorHandler implements ErrorHandler {
/**
* constructor to inject
*/
constructor(private injector: Injector, public dialog: MatDialog) {}
/**
* Function to handle errors
*
* @param (error) error passed to function
*/
handleError(error: Error) {
console.log('error (global): ', error);
const errorService = this.injector.get(ErrorService);
const logger = this.injector.get(LoggerService);
const location = this.injector.get(LocationStrategy);
// Message variable to hold error message
let errorMessage;
// Variable to hold url location of error
const url = location instanceof PathLocationStrategy ? location.path() : '';
console.log('url: ', url);
// check if error is a client error
if (error instanceof Error) {
// Client error message from error service
errorMessage = errorService.getClientMessage(error);
// Open dialog and display error message
this.openDialog(errorMessage);
}
// get the stack trace, lets grab the last 10 stacks only
StackTrace.fromError(error).then(stackframes => {
const stackString = stackframes
.splice(0, 20)
.map(function(sf) {
return sf.toString();
})
.join();
/**
* Function to log errors to api and mantis
*
* @param (errorMessage) error message passed to function
* @param (url) url passed to function
* @param (stackString) stackString passed to function
*/
logger.createErrorLog(errorMessage, url, stackString).subscribe(
result => {
console.log('log filed');
},
(err: any) => console.log(err)
);
});
return throwError(error);
}
/**
* Function to open dialog to display error
*
* @param (data) error data to display
*/
openDialog(data): void {
const dialogRef = this.dialog.open(ErrorDialogComponent, {
width: '60%',
data: data
});
// Code to run after the dialog is closed
dialogRef.afterClosed().subscribe(result => {
// Redirect back to home (dashboard)?
});
}
}
Так есть способ перехватить 404 код и выполнить перенаправление, но не вызывать глобальный обработчик ошибок?