Как правильно обработать ошибки?
Есть такое задание:
Написать функцию getRepeatableData, которая принимает на вход три параметра:
getData - функция, возвращающая данные со стороннего источника. Может генерировать ошибки (см ниже)
key - аргумент, с которым нужно вызвать getData
maxRequestsNumber- максимальное количество вызовов getData функции. Если этот параметр отсутствует - повторяем бесконечное количество раз.
getRepeatableData(getData, key, maxRequestNumber);
Функция getRepeatableData должна вызывать getData и обрабатывать ошибки по условию:
Если вызов
getDataвозвращает ошибку NotFoundError, то мы пробрасываем исключение.Если вызов
getDataвозвращает ошибкуTemporaryError, то мы должны делать повторный вызовgetDataфункции. Кол-во таких вызовов не должно превышать значениеmaxRequestsNumber. Если кол-во повторного вызова превышаетmaxRequestsNumber, то функция getRepeatableData должна пробрасывать ошибкуAttemtsLimitExceeded.Если getData выполняется без ошибок - функция должна вернуть то, что вернула
getData. Пример:const getData = (key) => 'hello' + key; const res = getRepeatableData(getData, '1', 3); // 'hello1'
И мой вариант кода:
class AttemptsLimitExceeded extends Error {
constructor(){
super('Max attempts limit exceed');
this.name = 'AttemptsLimitExceeded';
}
}
class NotFoundError extends Error {
constructor(){
super('Not found');
this.name = 'NotFoundError';
}
}
class TemporaryError extends Error {
constructor(){
super('TemporaryError');
this.name = 'TemporaryError';
}
}
function getRepeatableData(getData, key, maxRequestsNumber) {
let output;
try{
output = getData(key);
}
catch(e){
if(e instanceof NotFoundError)
throw e;
else if(e instanceof TemporaryError)
return getRepeatableData(getData, key, maxRequestsNumber--)
}
if (){
throw new AttemptsLimitExceeded;}// не знаю как написать условие
return output;
}
Как исправить?
Ответы (2 шт):
Как-то так:
class AttemptsLimitExceeded extends Error {
constructor() {
super('Max attempts limit exceed');
this.name = 'AttemptsLimitExceeded';
}
}
class NotFoundError extends Error {
constructor() {
super('Not found');
this.name = 'NotFoundError';
}
}
class TemporaryError extends Error {
constructor() {
super('TemporaryError');
this.name = 'TemporaryError';
}
}
function getRepeatableData(getData, key, maxRequestsNumber) {
let output;
try {
output = getData(key);
} catch (e) {
if (e instanceof NotFoundError) {
return e;
}
if (e instanceof TemporaryError) {
--maxRequestsNumber;
console.log(maxRequestsNumber);
if (maxRequestsNumber > 0) {
return getRepeatableData(getData, key, maxRequestsNumber);
} else {
return new AttemptsLimitExceeded();
}
}
}
return output;
}
const getData = (key) => {
if (key && key < 3) {
return 'hello' + key;
}
if (!key) {
throw new NotFoundError();
}
if (+key > 3) {
throw new TemporaryError();
}
}
res = getRepeatableData(getData, '', 3); //NotFoundError: Not found
console.log(res);
res = getRepeatableData(getData, '2', 3); //hello2
console.log(res);
res = getRepeatableData(getData, '4', 3); //Uncaught AttemptsLimitExceeded: Max attempts limit exceed
console.log(res);
AttemptsLimitExceeded нужно выбрасывать, когда попыток больше не осталось, а значит maxRequestsNumber == 0.
Таким образом достаточно добавить это условие в начало функции:
function getRepeatableData(getData, key, maxRequestsNumber) {
if (maxRequestsNumber == 0){
throw new AttemptsLimitExceeded;
}
try{
return getData(key);
}
catch(e){
if(e instanceof TemporaryError)
return getRepeatableData(getData, key, maxRequestsNumber-1)
// if(e instanceof NotFoundError) // можно убрать, так как пробрасывать надо все ошибки кроме TemporaryError
throw e;
}
}