nhttp_error (nhttp_lib v1.0.0)

View Source

Unified error handling for nhttp HTTP library.

Provides a consistent error taxonomy across client and server components. All errors use the format {error, {Category, Reason}} where Category identifies the error domain and Reason provides specific details.

Error Categories

  • connection - Connection establishment failures
  • request - Request/response cycle failures
  • http2 - HTTP/2 protocol-specific errors
  • pool - Connection pool errors
  • server - Server-side acceptor / listener / handler failures

Usage

case connect(Host, Port) of
    {ok, Conn} -> {ok, Conn};
    {error, econnrefused} -> nhttp_error:connect_refused(econnrefused);
    {error, timeout} -> nhttp_error:connect_timeout()
end.

case nhttpc:get(Url) of
    {ok, Resp} -> handle_response(Resp);
    {error, {connection, _}} -> retry_with_backoff();
    {error, {request, {timeout, _}}} -> return_504();
    {error, {pool, checkout_timeout}} -> return_503()
end.

case nhttp_error:is_retryable(Error) of
    true -> retry_request();
    false -> return_error()
end.

Summary

Functions

Accept socket was closed.

File descriptor limit reached during accept (retryable).

Accept timed out waiting for a new connection.

ALPN protocol negotiation failed.

Server is at connection capacity.

Body receive timed out after the specified duration.

Get the category of an error.

Timed out waiting for a connection from the pool.

Connection attempt failed with the given POSIX error.

Connection is not ready for use.

Connection was refused by the remote host.

Connection attempt timed out.

Connection attempt timed out after the specified duration.

Connection was closed during request processing.

Connection was closed with a retryable or unexpected tag.

Connection is in the process of closing.

File operation failed during request processing.

File operation failed for the given path.

Send blocked by HTTP/2 flow control window.

HTTP/2 flow control error.

Format error for logging.

Received GOAWAY frame with the given error code.

Received GOAWAY frame, marked as retryable.

HTTP/2 connection-level error.

HTTP/2 protocol error.

Handler init callback failed.

Check if error is retryable (connection-level or transient). Retryable errors are those where a fresh connection or retry might succeed.

Check if error is transient (may succeed on immediate retry). Transient errors are a subset of retryable errors where the issue is likely temporary (e.g., connection reset vs. server down).

Listen socket could not be opened.

Received a malformed response that could not be parsed.

Maximum number of redirects exceeded.

Required configuration key is missing.

No connections available in the pool.

Normalize raw errors into structured t() tuples. Converts various error formats from sockets, TLS, and protocol layers into a consistent categorized format.

Connection pool is draining and not accepting new requests.

Connection pool is exhausted.

Protocol-level error on a server connection.

HTTP/2 rate limiting applied by the peer.

Error receiving data from the socket.

Redirect loop detected at the given URL.

Request timed out.

Request timed out after the specified duration.

Response body exceeded the maximum allowed size.

Error sending data on the socket.

Server socket error.

Server-side stream was closed.

HTTP/2 stream was cancelled.

HTTP/2 stream was closed.

HTTP/2 stream was refused by the peer (retryable).

HTTP/2 stream was reset with the given error code.

Response stream was stopped by the caller.

Response stream was stopped with accumulated partial data.

TLS handshake or protocol error.

Upload processing failed.

WebSocket protocol error.

WebSocket upgrade handshake failed.

Types

category()

-type category() :: connection | request | http2 | pool | server.

reason()

-type reason() :: #{type := atom(), _ => _}.

t()

-type t() :: {error, {category(), reason()}}.

Functions

accept_closed()

-spec accept_closed() -> t().

Accept socket was closed.

accept_emfile()

-spec accept_emfile() -> t().

File descriptor limit reached during accept (retryable).

accept_timeout()

-spec accept_timeout() -> t().

Accept timed out waiting for a new connection.

alpn_error(Reason)

-spec alpn_error(term()) -> t().

ALPN protocol negotiation failed.

at_capacity()

-spec at_capacity() -> t().

Server is at connection capacity.

body_timeout(Timeout)

-spec body_timeout(timeout()) -> t().

Body receive timed out after the specified duration.

category/1

-spec category(t() | term()) -> category() | unknown.

Get the category of an error.

checkout_timeout()

-spec checkout_timeout() -> t().

Timed out waiting for a connection from the pool.

connect_failed(Posix)

-spec connect_failed(inet:posix()) -> t().

Connection attempt failed with the given POSIX error.

connect_not_ready()

-spec connect_not_ready() -> t().

Connection is not ready for use.

connect_refused(Posix)

-spec connect_refused(inet:posix()) -> t().

Connection was refused by the remote host.

connect_timeout()

-spec connect_timeout() -> t().

Connection attempt timed out.

connect_timeout(Timeout)

-spec connect_timeout(timeout()) -> t().

Connection attempt timed out after the specified duration.

connection_closed()

-spec connection_closed() -> t().

Connection was closed during request processing.

connection_closed(Tag)

-spec connection_closed(retryable | unexpected) -> t().

Connection was closed with a retryable or unexpected tag.

connection_closing()

-spec connection_closing() -> t().

Connection is in the process of closing.

file_error(Operation, Reason)

-spec file_error(atom(), term()) -> t().

File operation failed during request processing.

file_error(Operation, Path, Reason)

-spec file_error(atom(), file:filename(), term()) -> t().

File operation failed for the given path.

flow_control_blocked(Window, Size)

-spec flow_control_blocked(integer(), pos_integer()) -> t().

Send blocked by HTTP/2 flow control window.

flow_control_error(Reason)

-spec flow_control_error(term()) -> t().

HTTP/2 flow control error.

format/1

-spec format(t() | term()) -> iodata().

Format error for logging.

goaway(ErrorCode)

-spec goaway(nhttp_h2:error_code()) -> t().

Received GOAWAY frame with the given error code.

goaway/2

-spec goaway(nhttp_h2:error_code(), retryable) -> t().

Received GOAWAY frame, marked as retryable.

h2_connection_error(ErrorCode)

-spec h2_connection_error(atom()) -> t().

HTTP/2 connection-level error.

h2_error(Reason)

-spec h2_error(term()) -> t().

HTTP/2 protocol error.

handler_init_error(Reason)

-spec handler_init_error(term()) -> t().

Handler init callback failed.

is_retryable/1

-spec is_retryable(t() | term()) -> boolean().

Check if error is retryable (connection-level or transient). Retryable errors are those where a fresh connection or retry might succeed.

is_transient/1

-spec is_transient(t() | term()) -> boolean().

Check if error is transient (may succeed on immediate retry). Transient errors are a subset of retryable errors where the issue is likely temporary (e.g., connection reset vs. server down).

listen_failed(Posix)

-spec listen_failed(inet:posix()) -> t().

Listen socket could not be opened.

malformed_response(ParseError, Data)

-spec malformed_response(atom(), binary()) -> t().

Received a malformed response that could not be parsed.

max_redirects(Count)

-spec max_redirects(non_neg_integer()) -> t().

Maximum number of redirects exceeded.

missing_config(Key)

-spec missing_config(atom()) -> t().

Required configuration key is missing.

no_connections()

-spec no_connections() -> t().

No connections available in the pool.

normalize/1

-spec normalize(term()) -> t() | {error, term()}.

Normalize raw errors into structured t() tuples. Converts various error formats from sockets, TLS, and protocol layers into a consistent categorized format.

pool_draining()

-spec pool_draining() -> t().

Connection pool is draining and not accepting new requests.

pool_exhausted(Reason)

-spec pool_exhausted(term()) -> t().

Connection pool is exhausted.

protocol_error(Reason)

-spec protocol_error(atom()) -> t().

Protocol-level error on a server connection.

rate_limited()

-spec rate_limited() -> t().

HTTP/2 rate limiting applied by the peer.

recv_error(Posix)

-spec recv_error(inet:posix()) -> t().

Error receiving data from the socket.

redirect_loop(Url)

-spec redirect_loop(binary()) -> t().

Redirect loop detected at the given URL.

request_timeout()

-spec request_timeout() -> t().

Request timed out.

request_timeout(Timeout)

-spec request_timeout(timeout()) -> t().

Request timed out after the specified duration.

response_too_large(Size, MaxSize)

-spec response_too_large(non_neg_integer(), non_neg_integer()) -> t().

Response body exceeded the maximum allowed size.

send_error(Posix)

-spec send_error(inet:posix()) -> t().

Error sending data on the socket.

server_socket_error(Posix)

-spec server_socket_error(inet:posix()) -> t().

Server socket error.

server_stream_closed(StreamId)

-spec server_stream_closed(non_neg_integer()) -> t().

Server-side stream was closed.

stream_cancelled()

-spec stream_cancelled() -> t().

HTTP/2 stream was cancelled.

stream_closed/1

-spec stream_closed(graceful | term()) -> t().

HTTP/2 stream was closed.

stream_refused()

-spec stream_refused() -> t().

HTTP/2 stream was refused by the peer (retryable).

stream_reset(ErrorCode)

-spec stream_reset(nhttp_h2:error_code()) -> t().

HTTP/2 stream was reset with the given error code.

stream_stopped(Reason)

-spec stream_stopped(term()) -> t().

Response stream was stopped by the caller.

stream_stopped(Reason, Acc)

-spec stream_stopped(term(), term()) -> t().

Response stream was stopped with accumulated partial data.

tls_error(Reason)

-spec tls_error(term()) -> t().

TLS handshake or protocol error.

upload_error(Reason)

-spec upload_error(term()) -> t().

Upload processing failed.

ws_error(Reason)

-spec ws_error(term()) -> t().

WebSocket protocol error.

ws_upgrade_error(Reason)

-spec ws_upgrade_error(term()) -> t().

WebSocket upgrade handshake failed.