Практика: Обработка ошибок и паники
Онлайн редактор кода для Go
Здесь вы можете попробовать свои силы в программировании на языке Go. Для этого мы предоставляем вам онлайн редактор кода, в котором вы можете написать свой код и запустить его.
❗️ При обновлении страницы код пропадёт, по этому, сохраните свой код куда-нибудь, если он важный.
Задание 1 — Безопасный делитель с контекстом
Задание 1: Безопасный делитель
⏱️ Примерное время: 10-15 минутФункция SafeDivide(a, b float64) (float64, error). Если b == 0 — верни ошибку с контекстом через fmt.Errorf.
Требования:
- если b == 0 —
return 0, fmt.Errorf("деление %.2f на ноль недопустимо", a) - в main: если err != nil — выведи ошибку красным (или с эмодзи ⚠️)
- если всё ок — результат с двумя знаками после запятой
Пример вывода:
10.0 / 2.0 = 5.00 ✅
15.5 / 0.0 → ⚠️ деление 15.50 на ноль недопустимо
Задание 2 — Валидация возраста с кастомной ошибкой
Задание 2: Валидация возраста
⏱️ Примерное время: 15-20 минутСоздай тип AgeError struct { Age int; Message string }. Реализуй Error(). Функция CheckAge(age int) error.
Требования:
- структура
AgeError { Age int; Message string } - метод
Error() string→ fmt.Sprintf("возраст %d: %s", e.Age, e.Message) - проверки: < 0, > 150
- в main: type assertion
if ae, ok := err.(AgeError); ok { … }
Пример вывода:
Возраст 25: всё в порядке ✓
Возраст -5: возраст не может быть отрицательным ✗
Задание 3 — Множественная валидация (errors.Join)
Задание 3: Множественная валидация пользователя
⏱️ Примерное время: 20-25 минутФункция ValidateUser(name, email string, age int) error. Собери все ошибки через errors.Join.
Требования:
- проверки: имя не пустое и не только пробелы, email содержит
@, возраст 0–150 - собирай ошибки в слайс
[]error, затемreturn errors.Join(errs...) - в main: если err != nil — выведи каждую ошибку отдельной строкой
Пример вывода:
Ошибки валидации:
имя обязательно
некорректный email
возраст должен быть от 0 до 150
Задание 4 — Паника при критической ошибке
Задание 4: Аварийная остановка ракеты
⏱️ Примерное время: 15-20 минутФункция LaunchRocket(fuel int). Если топлива < 100 — паника. В main перехвати панику через defer + recover.
Требования:
if fuel < 100 { panic("недостаточно топлива") }- в main:
defer func() { if r := recover(); r != nil { fmt.Printf("Авария! %v\nЭкипаж в безопасности", r) } }() - после recover можно продолжить работу (например, "миссия отменена")
Пример вывода:
Запускаем ракету...
Авария! недостаточно топлива
Экипаж в безопасности
Миссия отменена
Задание 5 — Логгер ошибок с slog
Задание 5: Логгер ошибок с slog
⏱️ Примерное время: 15-20 минутСоздай глобальный slog-логгер. Пиши в него ошибки с уровнем Error и атрибутами (operation, err).
Требования:
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})))- функция
LogError(msg string, err error, attrs ...any) - используй
slog.Error(msg, "err", err, attrs...) - в main симулируй 3–5 ошибок
Пример вывода:
time=... level=ERROR msg="не удалось открыть файл" err="open config.json: no such file" operation=load_config
Задание 6 — Chain of errors (обёртывание)
Задание 6: Цепочка ошибок
⏱️ Примерное время: 25-35 минутФункции: ReadFile → ParseConfig → ValidateConfig. Каждая оборачивает ошибку через %w. В main проверяй errors.Is и errors.As.
Требования:
ReadFile(path) ([]byte, error)→fmt.Errorf("не удалось прочитать %s: %w", path, err)ParseConfig(data []byte) (Config, error)→%wValidateConfig(cfg Config) error→ кастомная ошибка или fmt.Errorf- в main:
errors.Is(err, os.ErrNotExist),errors.As(err, &target)
Пример вывода:
Ошибка: не удалось прочитать config.json: open config.json: no such file or directory
Файл точно не найден
Задание 7 — Итоговое: Надёжный загрузчик конфига
Задание 7: Надёжный загрузчик конфига (итоговое)
⏱️ Примерное время: 35-50 минутПрограмма загружает config.json. Обрабатывай все возможные ошибки: файл не найден, неверный JSON, невалидные значения. Логируй через slog.
Требования:
- структура
Config { Name string; Age int; Email string } - функция
LoadConfig(path string) (Config, error) - используй
errors.Is,errors.As,errors.Join - логируй через
slog.Errorс атрибутами - если файл не найден — верни дефолтный конфиг и залогируй Warn
Пример вывода:
WARN Конфиг не найден — использую значения по умолчанию
Загружен конфиг: {Artem 28 artem@example.com}
Ошибки — это не враги, а друзья.
Проверяй их явно, оборачивай для контекста, логируй через slog — и твой код будет надёжным и понятным.