Я реализую глобальный обработчик ошибок для своего Angular 9 приложения и пытаюсь заставить его перехватывать ошибки, создаваемые внешней службой, которая отвечает за выполнение всех моих вызовов API с использованием Ax ios. Я планирую в конечном итоге переключиться на использование HTTP-модуля и перехватчиков Angular для выполнения всех моих вызовов API, но пока я ограничен использованием моей внешней службы.
Вот моя проблема - когда возникает ошибка происходит в моем внешнем методе обслуживания, он перехватывается моим глобальным обработчиком ошибок как неперехваченное обещание. В приведенном ниже примере я перехватываю / выкидываю ошибку, чтобы быть более явной, а также в моей реальной реализации я преобразовываю ошибку в другой настраиваемый тип ошибки.
Другими словами, я способен отловить ошибку и зарегистрировать ее в обычном режиме (можно увидеть все мои данные об ошибках), но когда я повторно выбрасываю ее в блоке try / catch, чтобы мой глобальный обработчик ошибок мог ее обработать, это становится необработанным отклонением обещания. Может ли кто-нибудь помочь мне понять, почему и как я могу получить доступ к объекту обнаруженной ошибки в моем глобальном обработчике ошибок?
Ниже приведены несколько фрагментов, которые помогут вам лучше понять (удаление всех несущественных частей):
Служба данных
// DataService.ts
export class DataService {
protected axios: AxiosInstance;
public constructor(config) {
this.axios = this.getAxiosInstance(config);
}
public getAxiosInstance = (config: Partial<ServiceConfig>): AxiosInstance => {
// create and configure axios...
this.axios.interceptors.response.use(
response => response,
error => (error) = this.errorHandler(error),
);
return this.axios;
};
protected errorHandler(error: AxiosError): Promise<AxiosError> {
const errorObject: ErrorObject = {
error: {
contextType: 'none',
status: 500,
message: 'Oops! Something went wrong. Please try again.'
}
}
if (error.response) {
return Promise.reject(error.response.data);
} else {
this.error.next(errorObject);
return Promise.reject(errorObject);
}
}
public async fetchData() {
const result = await this.axios.get('get/data/url');
return result.data;
}
}
Angular Служба
// AppService.ts
import { DataService } from '..';
const config = {...}
@Injectable()
export class AppService {
service: DataService
constructor() {
this.service = new DataService(config);
}
async fetchData() {
try {
await this.service.fetchData();
} catch(e) {
console.log(e); // 'data: {context: '..', message: '..', status: '..', ...}'
throw new Error('Oh Snap'); // Error: Uncaught (in promise): Error: Oh Snap
}
}
}
Глобальный обработчик ошибок
@Injectable({
providedIn: 'root'
})
export class GlobalErrorHandler implements ErrorHandler {
constructor(private injector: Injector) {}
handleError(error): void {
if (error instanceof HttpErrorResponse) {
// Server Error Using Angular's HTTP Client Module
console.log('angular http module response error', { error });
} else if (error instanceof Error) {
// Server Error Using Angular's HTTP Client Module
console.log('custom http error', { error });
} else {
// Client Error
console.log('client error', { error });
}
console.error(error);
}
}
Мой текущий способ обхода - обернуть throw
в блоке catch в setTimeout()
, например:
// AppService.ts
async fetchData() {
try {
await this.service.fetchData();
} catch(e) {
setTimeout(() => {
throw new Error('Oh Snap'); // Error: Oh Snap
})
}
}