Current section

Files

Jump to
dream src dream@http@error.erl
Raw

src/dream@http@error.erl

-module(dream@http@error).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream/http/error.gleam").
-export([to_status_code/1, message/1]).
-export_type([error/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Dream unified error type\n"
"\n"
" A single error type used throughout Dream applications for both\n"
" HTTP-level validation errors and domain-level operation errors.\n"
" This eliminates the need for error conversion between layers.\n"
"\n"
" ## Philosophy\n"
"\n"
" Instead of having separate error types for HTTP validation, database operations,\n"
" and business logic, Dream uses one unified Error type. This means you can return\n"
" errors from any layer without conversion, and the type system tracks them naturally.\n"
"\n"
" ## Usage\n"
"\n"
" Return errors from controllers, models, or operations using the same type:\n"
"\n"
" ```gleam\n"
" import dream/http/error.{type Error, BadRequest, NotFound}\n"
" import gleam/result\n"
"\n"
" pub fn get_user(db: Connection, id: Int) -> Result(User, Error) {\n"
" case query_user(db, id) {\n"
" Ok(user) -> Ok(user)\n"
" Error(Nil) -> Error(NotFound(\"User not found\"))\n"
" }\n"
" }\n"
"\n"
" pub fn create_user(db: Connection, name: String) -> Result(User, Error) {\n"
" case validate_name(name) {\n"
" False -> Error(BadRequest(\"Name must not be empty\"))\n"
" True -> insert_user(db, name)\n"
" }\n"
" }\n"
" ```\n"
"\n"
" ## Converting to Responses\n"
"\n"
" Use `to_status_code()` and `message()` to convert errors to HTTP responses:\n"
"\n"
" ```gleam\n"
" import dream/http/error\n"
" import dream/http/response\n"
" import gleam/json\n"
"\n"
" case get_user(db, id) {\n"
" Ok(user) -> \n"
" response.json_response(200, user_to_json(user))\n"
" Error(err) -> \n"
" response.json_response(\n"
" error.to_status_code(err),\n"
" json.object([#(\"error\", json.string(error.message(err)))])\n"
" )\n"
" }\n"
" ```\n"
).
-type error() :: {bad_request, binary()} |
{unauthorized, binary()} |
{forbidden, binary()} |
{not_found, binary()} |
{unprocessable_content, binary()} |
{internal_server_error, binary()}.
-file("src/dream/http/error.gleam", 164).
?DOC(
" Convert Error to HTTP status code\n"
"\n"
" Maps each error variant to its corresponding HTTP status code.\n"
" Use this when building HTTP responses from errors.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import dream/http/error.{type Error, NotFound}\n"
" import dream/http/response\n"
"\n"
" let err = NotFound(\"User not found\")\n"
" let status = error.to_status_code(err) // Returns 404\n"
" response.json_response(status, error_json(err))\n"
" ```\n"
).
-spec to_status_code(error()) -> integer().
to_status_code(Error) ->
case Error of
{bad_request, _} ->
400;
{unauthorized, _} ->
401;
{forbidden, _} ->
403;
{not_found, _} ->
404;
{unprocessable_content, _} ->
422;
{internal_server_error, _} ->
500
end.
-file("src/dream/http/error.gleam", 195).
?DOC(
" Extract the error message from an Error\n"
"\n"
" Returns the message string from any error variant.\n"
" Useful when building error responses or logging.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import dream/http/error.{type Error, BadRequest}\n"
" import gleam/json\n"
"\n"
" let err = BadRequest(\"Invalid email format\")\n"
" let msg = error.message(err) // Returns \"Invalid email format\"\n"
"\n"
" // Build JSON error response\n"
" json.object([\n"
" #(\"error\", json.string(msg)),\n"
" #(\"status\", json.int(error.to_status_code(err)))\n"
" ])\n"
" ```\n"
).
-spec message(error()) -> binary().
message(Error) ->
case Error of
{bad_request, Msg} ->
Msg;
{unauthorized, Msg@1} ->
Msg@1;
{forbidden, Msg@2} ->
Msg@2;
{not_found, Msg@3} ->
Msg@3;
{unprocessable_content, Msg@4} ->
Msg@4;
{internal_server_error, Msg@5} ->
Msg@5
end.