Ловля топора ios ошибок в Angular - PullRequest
0 голосов
/ 19 июня 2020

Я реализую глобальный обработчик ошибок для своего 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
            })

        }
    }
...