Обработка ошибок является важным аспектом разработки надежных приложений на любом языке программирования. В Go разработчикам часто нужно различать исправимые и неисправимые ошибки, чтобы решить, следует ли перезапустить приложение или завершить его. В этом посте мы рассмотрим, как использовать глагол %w в обработке ошибок для переноса и определения исправимых и неисправимых ошибок в приложении Go.
Обзор кода
Предоставленный пример кода имитирует приложение обработки задач, которое сталкивается со случайными устранимыми и неустранимыми ошибками. Приложение использует глагол %w для переноса этих ошибок и обрабатывает их соответствующим образом:
package main
import (
"errors"
"fmt"
"math/rand"
"time"
)
var (
ErrRecoverable = errors.New("recoverable error")
ErrUnrecoverable = errors.New("unrecoverable error")
)
func processTask(taskID int) error {
// Simulate random errors for demonstration purposes
randomErr := rand.Intn(10)
fmt.Printf("randomErr: %d\n", randomErr)
switch randomErr {
case 0:
return fmt.Errorf("task %d failed with %w", taskID, ErrRecoverable)
case 1:
return fmt.Errorf("task %d failed with %w", taskID, ErrUnrecoverable)
default:
fmt.Printf("Task %d processed successfully\n", taskID)
return nil
}
}
func main() {
rand.Seed(time.Now().UnixNano())
const maxTasks = 100
for i := 0; i < maxTasks; {
err := processTask(i)
if err != nil {
if errors.Is(err, ErrRecoverable) {
fmt.Printf("Recoverable error occurred: %v. Restarting app...\n", err)
continue
} else if errors.Is(err, ErrUnrecoverable) {
fmt.Printf("Unrecoverable error occurred: %v. Terminating app...\n", err)
break
}
}
i++
}
}
Использование %w для переноса ошибок
Глагол %w используется с функцией fmt.Errorf для создания новой ошибки, включающей существующую ошибку. Это позволяет нам добавить больше контекста к сообщению об ошибке, сохраняя при этом исходную информацию об ошибке. В нашем примере мы используем %w, чтобы обернуть предопределенные ошибки ErrRecoverable и ErrUnrecoverable информацией, относящейся к задаче:
return fmt.Errorf("task %d failed with %w", taskID, ErrRecoverable)
return fmt.Errorf("task %d failed with %w", taskID, ErrUnrecoverable)
Обработка обернутых ошибок
В функции main мы обрабатываем ошибки, проверяя, являются ли они обернутыми ошибками, используя функцию errors.Is. Это позволяет нам идентифицировать исходный тип ошибки, сохраняя при этом дополнительный контекст, предоставляемый сообщением об ошибке:
if err != nil {
if errors.Is(err, ErrRecoverable) {
fmt.Printf("Recoverable error occurred: %v. Restarting app...\n", err)
continue
} else if errors.Is(err, ErrUnrecoverable) {
fmt.Printf("Unrecoverable error occurred: %v. Terminating app...\n", err)
break
}
}
Заключение
В этом посте мы продемонстрировали, как использовать глагол %w в обработке ошибок Go, чтобы различать исправимые и неисправимые ошибки. Оборачивая и идентифицируя определенные типы ошибок, разработчики могут создавать более отказоустойчивые приложения, которые могут разумно перезапускать или завершать работу в зависимости от характера возникшей ошибки. Этот подход способствует улучшению методов обработки ошибок, помогая разработчикам создавать приложения, которые являются более надежными и адаптивными к различным сценариям возникновения ошибок. Благодаря сочетанию обернутых ошибок и встроенных в Go функций проверки ошибок, таких как errors.Is, проще, чем когда-либо, реализовать сложные стратегии обработки ошибок в ваших приложениях Go.
Если вам нравится читать статьи на Medium и вы заинтересованы в том, чтобы стать участником, я буду рад поделиться с вами своей реферальной ссылкой!