Проверяет понимание различий между временными ошибками, которые можно повторить, и постоянными ошибками, которые требуют изменения кода или данных.
При разработке распределённых систем и работе с внешними сервисами важно понимать, какие ошибки можно исправить повторной попыткой, а какие — нет. Это позволяет строить надёжные системы, которые корректно обрабатывают сбои и не перегружают сервисы бесконечными запросами.
Retriable ошибки — это временные сбои, которые возникают из-за внешних факторов: потеря соединения, таймаут, перегрузка сервера (HTTP 503), временная недоступность базы данных. Они обычно исчезают через короткое время, поэтому повторная попытка может быть успешной. Примеры: ECONNRESET в Node.js, ConnectionError в PostgreSQL, HTTP 429 (Too Many Requests).
Non-retriable ошибки — это постоянные сбои, вызванные логическими проблемами: неверные входные данные, отсутствие прав доступа, несуществующий ресурс (HTTP 404), нарушение бизнес-правил. Повторная попытка не изменит результат, так как причина не в временном сбое, а в самом запросе или состоянии системы.
Обычно тип ошибки определяется по коду HTTP или типу исключения. Например, в HTTP: 5xx (кроме 501) — retriable, 4xx — non-retriable. В библиотеках часто есть специальные классы ошибок, например, RetryableError в AWS SDK. Также можно использовать эвристики: если ошибка связана с сетью или таймаутом — retriable, если с валидацией — нет.
async function fetchWithRetry(url, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url);
if (response.ok) return response;
if (response.status >= 500 || response.status === 429) {
// retriable: серверная ошибка или перегрузка
await delay(2 ** attempt * 1000); // экспоненциальная задержка
continue;
}
throw new Error(`Non-retriable: ${response.status}`);
} catch (err) {
if (err.name === 'TypeError' || err.message.includes('network')) {
// retriable: сетевая ошибка
await delay(2 ** attempt * 1000);
continue;
}
throw err; // non-retriable
}
}
throw new Error('Max retries exceeded');
}Различение retriable и non-retriable ошибок — ключевой навык для построения устойчивых систем. Используйте повторные попытки только для временных сбоев, применяйте экспоненциальную задержку и учитывайте идемпотентность операций, чтобы избежать побочных эффектов. Это снижает нагрузку на сервисы и повышает надёжность приложений.