{"id":13808896,"url":"https://github.com/MikaAK/elixir_error_message","last_synced_at":"2025-05-14T03:31:48.280Z","repository":{"id":39582290,"uuid":"424845857","full_name":"MikaAK/elixir_error_message","owner":"MikaAK","description":"Elixir error messages to make the errors within the system easier to expect and predict, as well as read ","archived":false,"fork":false,"pushed_at":"2023-09-28T10:10:28.000Z","size":71,"stargazers_count":33,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-17T20:10:38.432Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://learn-elixir.dev/blogs/safer-error-systems-in-elixir","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MikaAK.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-11-05T06:09:53.000Z","updated_at":"2024-11-13T12:33:32.000Z","dependencies_parsed_at":"2023-09-28T11:58:05.886Z","dependency_job_id":null,"html_url":"https://github.com/MikaAK/elixir_error_message","commit_stats":{"total_commits":44,"total_committers":2,"mean_commits":22.0,"dds":"0.022727272727272707","last_synced_commit":"a49288f56dfeabf717c51ac91114dad6c4c841c6"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Felixir_error_message","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Felixir_error_message/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Felixir_error_message/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Felixir_error_message/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MikaAK","download_url":"https://codeload.github.com/MikaAK/elixir_error_message/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225273287,"owners_count":17448080,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T01:01:54.464Z","updated_at":"2024-11-19T00:31:12.299Z","avatar_url":"https://github.com/MikaAK.png","language":"Elixir","funding_links":[],"categories":["Errors and Exception Handling"],"sub_categories":[],"readme":"ErrorMessage\n===\n[![Coverage](https://github.com/MikaAK/elixir_error_message/actions/workflows/coverage.yml/badge.svg)](https://github.com/MikaAK/elixir_error_message/actions/workflows/coverage.yml)\n[![Test](https://github.com/MikaAK/elixir_error_message/actions/workflows/test.yml/badge.svg)](https://github.com/MikaAK/elixir_error_message/actions/workflows/test.yml)\n[![Dialyzer](https://github.com/MikaAK/elixir_error_message/actions/workflows/dialyzer.yml/badge.svg)](https://github.com/MikaAK/elixir_error_message/actions/workflows/dialyzer.yml)\n[![Credo](https://github.com/MikaAK/elixir_error_message/actions/workflows/credo.yml/badge.svg)](https://github.com/MikaAK/elixir_error_message/actions/workflows/credo.yml)\n[![codecov](https://codecov.io/gh/MikaAK/elixir_error_message/branch/master/graph/badge.svg?token=V0JJA5AZ1H)](https://codecov.io/gh/MikaAK/elixir_error_message)\n[![Hex pm](http://img.shields.io/hexpm/v/error_message.svg?style=flat)](https://hex.pm/packages/error_message)\n\nThis library exists to simplify error systems in a code base\nand allow for a simple unified experience when using and reading\nerror messages around the code base\n\nThis creates one standard, that all errors should fit into the context\nof HTTP error codes, if they don't `:internal_server_error` should\nbe used and you can use the message and details to provide a further\nlevel of depth\n\n### Installation\n\nThe package can be installed by adding `error_message` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:error_message, \"~\u003e 0.2.0\"}\n  ]\nend\n```\n\nDocumentation can be found at [https://hexdocs.pm/error_message](https://hexdocs.pm/error_message).\n\n\n### Usage Example\n\n```elixir\niex\u003e id = 1\niex\u003e ErrorMessage.not_found(\"no user with id #{id}\", %{user_id: id})\n%ErrorMessage{\n  code: :not_found,\n  message: \"no user with id 1\",\n  details: %{user_id: 1}\n}\n\niex\u003e ErrorMessage.internal_server_error(\"critical internal error\", %{\n...\u003e   reason: :massive_issue_with_x\n...\u003e })\n%ErrorMessage{\n  code: :internal_server_error,\n  message: \"critical internal error\",\n  details: %{reason: :massive_issue_with_x}\n}\n```\n\n### Why is this important\nIf we want to have a good way to catch errors around our system as well as be able to\ndisplay errors that happen throughout our system, it's useful to have a common error\napi so we can predict what will come out of a system\n\nFor example if we used elixir through our server, we would be able to catch a not found\npretty easily since we can predict the error code coming in without needing to\nknow the message. This leads to more resilliant code since message changes won't break\nthe functionality of your application\n\n```elixir\n# Because our error system is setup with `find_user` we can easily\n# catch no users and have a solid backup plan\nwith {:error, %ErrorMessage{code: :not_found}} \u003c- find_user(%{name: \"bill\"}) do\n  create_user(%{name: \"bill\"})\nend\n```\n\n### Usage with Phoenix\nAnother benefit is error rendering to the frontend, because all our errors are part of\nthe HTTP error system, it's quite easy to now return the proper status codes and messages\nto our frontend clients. For example:\n\n```elixir\ndefmodule MyController do\n  def index(conn, param) do\n    case find_thing(params) do\n      {:ok, res} -\u003e json(conn, res)\n      {:error, e} -\u003e json_error(conn, e)\n    end\n  end\n\n  defp json_error(conn, %ErrorMessage{code: code} = e) do\n    conn\n      |\u003e put_status(code) # Plug.Conn\n      |\u003e json(ErrorMessage.to_jsonable_map(e))\n  end\nend\n```\n\n*This will also add a request_id from `Logger.metadata[:request_id]` when found*\n\n\n### Usage with Logger\nOntop of being useful for Phoenix we can also find some good use from this\nsystem and Logger, since `ErrorMessage` implements `String.Chars` protocol\n\n```elixir\ncase do_thing() do\n  {:ok, value} -\u003e {:ok, do_other_thing(value)}\n  {:error, e} = res -\u003e\n    Logger.error(\"[MyModule] \\#{e}\")\n    Logger.warn(to_string(e))\n\n    res\nend\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMikaAK%2Felixir_error_message","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMikaAK%2Felixir_error_message","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMikaAK%2Felixir_error_message/lists"}