Go
Ошибки и повторы
Один тип ошибки для каждого сбоя, сторожевое значение для каждого вида и повторы, которые не могут отправить дважды.
Обработка ошибки
_, err := client.Emails.Send(ctx, openemail.Body{ "from": "[email protected]", "to": "[email protected]", "subject": "Your September invoice", "text": "Invoice attached.",}) var failure *openemail.Error switch {case err == nil: fmt.Println("sent")case errors.Is(err, openemail.ErrValidation): errors.As(err, &failure) fmt.Println(failure.Code, failure.Param, failure.Message)case errors.Is(err, openemail.ErrRateLimited): errors.As(err, &failure) fmt.Println("try again in", failure.RetryAfter)case errors.Is(err, openemail.ErrTimeout): fmt.Println("no answer in time")default: return err}Каждый сбой представляет собой *openemail.Error. errors.Is сообщает, какого он вида, а errors.As даёт саму ошибку с тем, что о ней сказал API.
| Поле | Что в нём |
|---|---|
| Status | HTTP-статус или 0, когда ответ не пришёл. |
| Type, Code | Тип ошибки и код API, например validation_error и invalid_parameter. |
| Param | Поле, которое виновато, если такое есть. |
| RequestID | Идентификатор, который стоит указать, когда пишете в поддержку. |
| DocURL | Страница документации, объясняющая код. |
| RetryAfter | Сколько API попросил подождать. |
| Fields | Поля, которые отклонила форма подписки, каждое с Key и Error. |
| Body | Декодированное тело ответа. |
Виды сбоев
| Сторожевое значение | Когда оно совпадает |
|---|---|
| ErrAuthentication | Ключ или токен отклонён, с кодом 401. |
| ErrPermission | Этим учётным данным это не разрешено, с кодом 403. |
| ErrScopeMissing | Учётным данным не хватает области доступа, нужной вызову. |
| ErrStepUpRequired | Токен доступа сначала должен подтвердить код. |
| ErrNotFound | Ничего с таким идентификатором нет, с кодом 404. |
| ErrConflict | Изменение противоречит текущему состоянию, с кодом 409. |
| ErrValidation | Поле отклонено, с кодом 422. |
| ErrRateLimited | Слишком много запросов или лимит исчерпан, с кодом 429. |
| ErrInvalidRequest | Любой другой отказ в запросе. |
| ErrServer | Сбой API, со статусом 500 или выше. |
| ErrRetryable | Статус относится к тем, которые клиент повторяет. |
| ErrNetwork | Ответ не пришёл. |
| ErrTimeout | Ответ не пришёл до истечения таймаута. |
| ErrInvalidArgument | Сам вызов был неверным, и ничего не было отправлено. |
| ErrWebhookSignature | Доставка вебхука не прошла проверку. |
Отменённый контекст по-прежнему совпадает с context.Canceled, а истёкший крайний срок совпадает с context.DeadlineExceeded.
Что повторяется
- Чтения, отправки и любая запись, которую безопасно повторить, повторяются до
WithMaxRetriesраз. Любая другая запись отправляется один раз. - Статусы 408, 500, 502, 503 и 504 повторяются с задержкой, которая начинается с половины секунды и удваивается до восьми секунд.
- 429 повторяется, только если он несёт
Retry-Afterне больше минуты, и клиент ждёт столько же. - Соединение, которое оборвалось или превысило таймаут, повторяется так же.
Повторяемая отправка каждый раз несёт один и тот же ключ идемпотентности, поэтому API воспроизводит первое сообщение, а не отправляет второе.