Я предлагаю здесь вместо использования классов использовать функции, которые будут создавать структуры искомых ошибок. Поэтому мы не потеряем никакой информации из исходной ошибки, но мы также можем добавить некоторые метаданные для представления особого типа ошибки. Рассмотрим
// we are copying orginal error to not loose the data:
const createCustomerError = (e: Error) => ({...e, errorType: 'CREATE_CUSTOMER'});
const otherError = (e: Error) => ({...e, errorType: 'OTHER'});
Благодаря этому у вас есть трассировка стека, сообщение, а также дополнительная информация. Вы можете добавлять в любое время метаданные, которые вы хотите. Также было бы неплохо смоделировать такие ошибки в типе:
type ErrorType = 'CREATE_CUSTOMER' | 'OTHER' // can be also enum
type MyError = {errorType: ErrorType } & Error;
// also we should define our error function output as MyError:
const createCustomerError = (e: Error): MyError => ({...e, errorType: 'CREATE_CUSTOMER'});
const otherError = (e: Error): MyError => ({...e, errorType: 'OTHER'});
Благодаря этому типу вы можете создать обработчик со стандартным переключателем /, если он обрабатывает определенные ошибки, такие как:
// some parent handler which will handle those re thrown errors
switch(error.errorType) {
case 'CREATE_CUSTOMER':
someHandler();
break;
case 'OTHER':
someHandler2();
break;
default:
defaultErrrorHandler();
}
Lastно не в последнюю очередь. Использование функции конструктора ошибок выглядит так:
try {
this.stripe.customers.create({ ... });
} catch(e) {
throw createCustomerError(e);
}