Skip to content

Errors

Every failure raises a subclass of OneSmsError, so a single except OneSmsError catches everything the client can throw. Most of the time you catch the specific ones that need their own handling and let the rest bubble up.

Two kinds of failure

Problems fall into two groups: the ones caught before a request leaves your machine, and the ones that come back from the API.

OneSmsValidationError is raised locally, for example when the text is empty or the recipient list is too long. No request is sent. OneSmsConnectionError is raised when the network fails and the request could not be retried.

Everything the API rejects raises an OneSmsAPIError. It carries the HTTP status_code, the API error_code, the message, and the raw payload.

Catch what matters

from onesms import (
    InsufficientBalanceError,
    OneSmsAPIError,
    OneSmsConnectionError,
    OneSmsValidationError,
    RateLimitError,
)

try:
    client.send_notification(["994501234567"], "Hello")
except OneSmsValidationError as exc:
    print("Bad input:", exc)
except InsufficientBalanceError as exc:
    print("Top up:", exc.required, "have:", exc.balance)
except RateLimitError as exc:
    print("Slow down, retry after:", exc.retry_after)
except OneSmsConnectionError as exc:
    print("Network problem:", exc)
except OneSmsAPIError as exc:
    print(exc.status_code, exc.error_code, exc.message)

Order the except clauses from specific to general. Since the specific API errors all inherit from OneSmsAPIError, that clause has to come last.

The full list

Exception Raised for
OneSmsValidationError Local checks before a request is sent
OneSmsConnectionError Network failures that could not be retried
BadRequestError 400
AuthenticationError 401
InsufficientBalanceError 402, adds required and balance
PermissionDeniedError 403
NotFoundError 404
ConflictError 409
RateLimitError 429, adds retry_after
ServerError 5xx, adds msm_errno, msm_err_text, hint
OneSmsAPIError Base for any API error

InsufficientBalanceError, RateLimitError, and ServerError add the extra fields shown above, so you can read them straight off the exception instead of digging through the raw payload.