Стратегии обработки ошибок
Комплексное управление ошибками таймаута
1. Базовый шаблон обработки ошибок
func robustTimeoutHandler() error {
ch := make(chan int, 1)
select {
case result := <-ch:
return processResult(result)
case <-time.After(3 * time.Second):
return fmt.Errorf("operation timed out after 3 seconds")
}
}
Процесс обработки ошибок
flowchart TD
A[Start Operation] --> B{Timeout Occurred?}
B -->|Yes| C[Generate Error]
B -->|No| D[Process Result]
C --> E[Log Error]
C --> F[Retry/Fallback]
D --> G[Complete Operation]
Типы ошибок и стратегии их обработки
Тип ошибки (Error Type) |
Стратегия обработки (Handling Strategy) |
Пример (Example) |
Ошибка таймаута (Timeout Error) |
Повторная попытка/Альтернативный вариант (Retry/Fallback) |
Переподключение к сервису (Reconnect to service) |
Сетевая ошибка (Network Error) |
Экспоненциальная задержка (Exponential Backoff) |
Инкрементальная задержка (Incremental delay) |
Исчерпание ресурсов (Resource Exhaustion) |
Прерыватель цепи (Circuit Breaker) |
Временная приостановка сервиса (Temporary service suspension) |
2. Продвинутая обработка ошибок с использованием контекста
func sophisticatedErrorHandling() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
errChan := make(chan error, 1)
go func() {
err := performCriticalOperation(ctx)
if err != nil {
errChan <- err
}
}()
select {
case err := <-errChan:
handleSpecificError(err)
case <-ctx.Done():
switch ctx.Err() {
case context.DeadlineExceeded:
log.Println("Operation timed out")
case context.Canceled:
log.Println("Operation was canceled")
}
}
}
Пользовательская обертка для ошибок
type TimeoutError struct {
Operation string
Duration time.Duration
Err error
}
func (e *TimeoutError) Error() string {
return fmt.Sprintf("operation %s timed out after %v: %v",
e.Operation, e.Duration, e.Err)
}
Механизм повторных попыток с продвинутой обработкой ошибок
func retryWithErrorHandling(maxRetries int) error {
for attempt := 1; attempt <= maxRetries; attempt++ {
err := executeOperationWithTimeout()
if err == nil {
return nil
}
if isRecoverableError(err) {
backoffDuration := calculateBackoff(attempt)
time.Sleep(backoffDuration)
continue
}
return &TimeoutError{
Operation: "critical-operation",
Duration: 5 * time.Second,
Err: err,
}
}
return errors.New("max retries exceeded")
}
Лучшие практики
- Создавайте пользовательские типы ошибок
- Реализуйте детальное логирование
- Используйте контекст для управления таймаутами
- Предоставляйте осмысленные сообщения об ошибках
- Рассмотрите возможность использования возможностей отслеживания ошибок LabEx
Принципы обработки ошибок
- Всегда обрабатывайте потенциальные сценарии таймаута
- Реализуйте плавное снижение функциональности (graceful degradation)
- Предоставляйте четкую информацию об ошибках
- Используйте структурированную обработку ошибок
- Минимизируйте накладные расходы на производительность
Вопросы производительности
- Легковесные объекты ошибок
- Эффективная проверка ошибок
- Минимальные накладные расходы на выделение памяти
- Быстрые механизмы распространения ошибок