Ошибка как значение

В языке Go ошибки представлены интерфейсом error. Этот интерфейс содержит один метод Error() string, который возвращает текстовое описание ошибки. Ошибка как значение означает, что функция может возвращать ошибку наряду с основным результатом, и вызывающий код обязан проверить, не равна ли ошибка nil. Такой подход делает обработку ошибок явной и обязательной.

Синтаксис

goresult, err := someFunction()
if err != nil {
  // обработка ошибки
  return err
}
// использование result

Пример создания простой ошибки

Рассмотрим пример функции, которая возвращает ошибку с помощью errors.New:

gopackage main

import (
  "errors"
  "fmt"
)

func divide(a, b int) (int, error) {
  if b == 0 {
    return 0, errors.New("division by zero")
  }
  return a / b, nil
}

func main() {
  res, err := divide(10, 0)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(res)
}

Результат выполнения кода:

go"division by zero"

Пример с форматированием ошибки

Для создания ошибки с дополнительной информацией используется fmt.Errorf:

gopackage main

import (
  "fmt"
)

func validateAge(age int) error {
  if age < 0 {
    return fmt.Errorf("age cannot be negative: %d", age)
  }
  if age > 150 {
    return fmt.Errorf("age is too high: %d", age)
  }
  return nil
}

func main() {
  err := validateAge(-5)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println("age is valid")
}

Результат выполнения кода:

go"age cannot be negative: -5"

Пример обработки нескольких ошибок

Рассмотрим функцию, которая может возвращать несколько разных ошибок:

gopackage main

import (
  "errors"
  "fmt"
)

var ErrInvalidInput = errors.New("invalid input")
var ErrNotFound = errors.New("not found")

func processData(data string) (string, error) {
  if data == "" {
    return "", ErrInvalidInput
  }
  if data == "404" {
    return "", ErrNotFound
  }
  return "processed: " + data, nil
}

func main() {
  res, err := processData("")
  if err != nil {
    if errors.Is(err, ErrInvalidInput) {
      fmt.Println("input validation failed")
    } else if errors.Is(err, ErrNotFound) {
      fmt.Println("data not found")
    } else {
      fmt.Println(err)
    }
    return
  }
  fmt.Println(res)
}

Результат выполнения кода:

go"input validation failed"

Смотрите также

  • функцию errors.New,
    которая создает новую ошибку с текстовым сообщением
  • функцию errors.Is,
    которая проверяет, является ли ошибка конкретным типом
  • функцию errors.As,
    которая извлекает ошибку определенного типа
  • функцию fmt.Errorf,
    которая создает форматированную ошибку