diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-26 12:52:43 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-26 12:52:43 -0300 |
| commit | 42d8c12d2bd88462df8c3aac9449abbf98400084 (patch) | |
| tree | 564b07e68aed22c3aa4a066b822d731328fb4e97 /src/cepis_errors.f90 | |
| download | fortran-42d8c12d2bd88462df8c3aac9449abbf98400084.tar.gz | |
Initial import
Diffstat (limited to 'src/cepis_errors.f90')
| -rw-r--r-- | src/cepis_errors.f90 | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/cepis_errors.f90 b/src/cepis_errors.f90 new file mode 100644 index 0000000..5a86dec --- /dev/null +++ b/src/cepis_errors.f90 @@ -0,0 +1,83 @@ +!> Status codes returned by every fallible procedure in this library. +!> +!> Fortran has no exceptions, so every call that can fail takes an +!> `integer, intent(out) :: status` and a +!> `character(len=:), allocatable, intent(out) :: message`. `status` is one of +!> the parameters below; `message` is always allocated, and is the empty string +!> on success. +!> +!> The split is by **the decision the caller has to make**, not by the HTTP +!> status that caused it. `CEPIS_ERR_INVALID_CEP` and `CEPIS_ERR_NOT_FOUND` are +!> problems with the request: retrying returns the same answer more slowly. The +!> three transport errors below them may succeed later, and the client already +!> retried on its own before returning any of them. +module cepis_errors + implicit none + private + + !> The call succeeded. + integer, parameter, public :: CEPIS_OK = 0 + + !> The CEP is not 8 digits, or the API rejected it with a 400. + !> + !> Usually returned without any request being made: the client validates + !> the format before going to the network. + integer, parameter, public :: CEPIS_ERR_INVALID_CEP = 1 + + !> The CEP is well-formed but does not exist in the DNE database. + integer, parameter, public :: CEPIS_ERR_NOT_FOUND = 2 + + !> The API answered 429 on every attempt. `retry_after` carries what the + !> server asked for, in seconds, or a negative value when it did not say. + integer, parameter, public :: CEPIS_ERR_RATE_LIMITED = 3 + + !> The API answered 5xx on every attempt. `http_status` carries the status + !> seen on the last attempt. + integer, parameter, public :: CEPIS_ERR_SERVER = 4 + + !> The request never completed: DNS, refused connection, timeout, TLS. + integer, parameter, public :: CEPIS_ERR_NETWORK = 5 + + !> A success status came back with a body that cannot be parsed. + !> + !> In practice something between the caller and the API is answering + !> instead of it: a captive Wi-Fi portal, a corporate proxy, an HTML error + !> page. + integer, parameter, public :: CEPIS_ERR_INVALID_RESPONSE = 6 + + !> A configuration value is out of range. Not one of the six categories + !> above: it is a programming error, caught before any request is made. + integer, parameter, public :: CEPIS_ERR_CONFIG = 7 + + public :: cepis_status_name + +contains + + !> A short, stable, English name for a status code. + pure function cepis_status_name(status) result(name) + integer, intent(in) :: status + character(len=:), allocatable :: name + + select case (status) + case (CEPIS_OK) + name = 'ok' + case (CEPIS_ERR_INVALID_CEP) + name = 'invalid_cep' + case (CEPIS_ERR_NOT_FOUND) + name = 'not_found' + case (CEPIS_ERR_RATE_LIMITED) + name = 'rate_limited' + case (CEPIS_ERR_SERVER) + name = 'server_error' + case (CEPIS_ERR_NETWORK) + name = 'network_error' + case (CEPIS_ERR_INVALID_RESPONSE) + name = 'invalid_response' + case (CEPIS_ERR_CONFIG) + name = 'config_error' + case default + name = 'unknown' + end select + end function cepis_status_name + +end module cepis_errors |