{"id":31765350,"url":"https://github.com/jamesstonehill/api_error_handler","last_synced_at":"2025-10-10T00:15:46.668Z","repository":{"id":48916006,"uuid":"197969504","full_name":"jamesstonehill/api_error_handler","owner":"jamesstonehill","description":"A gem that helps you easily handle exceptions in your Rails API and return informative responses to the client.","archived":false,"fork":false,"pushed_at":"2022-04-12T10:08:05.000Z","size":81,"stargazers_count":27,"open_issues_count":3,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-07T12:10:39.043Z","etag":null,"topics":["actionpack","error-serializer","gem","json-api","rails","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/jamesstonehill.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-20T18:47:16.000Z","updated_at":"2025-06-02T17:48:42.000Z","dependencies_parsed_at":"2022-09-01T09:03:15.107Z","dependency_job_id":null,"html_url":"https://github.com/jamesstonehill/api_error_handler","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/jamesstonehill/api_error_handler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesstonehill%2Fapi_error_handler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesstonehill%2Fapi_error_handler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesstonehill%2Fapi_error_handler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesstonehill%2Fapi_error_handler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamesstonehill","download_url":"https://codeload.github.com/jamesstonehill/api_error_handler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesstonehill%2Fapi_error_handler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002388,"owners_count":26083356,"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","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["actionpack","error-serializer","gem","json-api","rails","ruby"],"created_at":"2025-10-10T00:15:43.767Z","updated_at":"2025-10-10T00:15:46.655Z","avatar_url":"https://github.com/jamesstonehill.png","language":"Ruby","readme":"# ApiErrorHandler\n[![Build Status](https://travis-ci.org/jamesstonehill/api_error_handler.svg?branch=master)](https://travis-ci.org/jamesstonehill/api_error_handler)\n\nAre your API error responses not all that you want them to be? If so, you've\nfound the right gem! `api_error_handler` handles all aspects of returning\ninformative, spec-compliant responses to clients when your application\nencounters an error in the course of processing a response.\n\nThis \"handling\" includes:\n- __Error serialization__: each response will include a response body that\n    gives some information on the type of error that your application\n    encountered. See the [Responses Body Options](#response-body-options)\n    section for details and configuration options.\n- __Status code setting__: `api_error_handler` will set the HTTP status code of\n    the response based on the type of error that is raised. For example, when an\n    `ActiveRecord::RecordNotFound` error is raised, it will set the response\n    status to 404. See the [HTTP Status Mapping](#http-status-mapping) section\n    for details and configuration options.\n- __Error reporting__: If you use a 3rd party bug tracking\n    tool like Honeybadger or Sentry, `api_error_handler` will notify this\n    service of the error for you so you don't have to!\n- __Content type setting__: `api_error_handler` will set the content type of the\n    response based on the format of response body.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'api_error_handler'\n```\n\nAnd then execute:\n\n    $ bundle install\n\n## Usage\n\nTo get started, all you need to do is invoke `handle_api_errors` inside your\ncontroller like so:\n\n```ruby\nclass MyController \u003c ActionController::API\n  handle_api_errors()\n\n  def index\n    raise \"Something is very very wrong!\"\n  end\nend\n```\n\nNow when you go to `MyController#index`, your API will return the following\nresponse:\n\n```json\nHTTP/1.1 500 Internal Server Error\nContent-Type: application/json\n\n{\n  \"error\": {\n    \"title\":\"Internal Server Error\",\n    \"detail\":\"Something is very very wrong!\"\n  }\n}\n```\n\n### Error handling options\n\n`handle_api_errors` implements a bunch of (hopefully) sensible defaults so that\nall you need to do is invoke `handle_api_errors()` in your controller to get\nuseful error handling! However, in all likelihood you'll want to override some\nof these options. This section gives details on the various options available\nfor configuring the `api_error_handler`.\n\n#### Response Body Options\nBy default, `handle_api_errors` picks the `:json` format for serializing errors.\nHowever, this gem comes with a number of other formats for serializing your\nerrors.\n\n##### JSON (the default)\n```ruby\n  handle_api_errors(format: :json)\n  # Or\n  handle_api_errors()\n```\n\n```json\nHTTP/1.1 500 Internal Server Error\nContent-Type: application/json\n\n{\n  \"error\": {\n    \"title\":\"Internal Server Error\",\n    \"detail\":\"Something is very very wrong!\"\n  }\n}\n```\n\n##### JSON:API\nIf your API follows the `JSON:API` spec, you'll want to use the `:json_api`\nformat option.\n\n```ruby\n  handle_api_errors(format: :json_api)\n```\n\nResponses with this format will follow the `JSON:API` [specification for error\nobjects](https://jsonapi.org/format/#error-objects). This will look something\nlike this:\n\n```json\nHTTP/1.1 500 Internal Server Error\nContent-Type: application/vnd.api+json\n\n{\n  \"errors\": [\n    {\n      \"status\":\"500\",\n      \"title\":\"Internal Server Error\",\n      \"detail\":\"Something is very very wrong!\"\n    }\n  ]\n}\n```\n\n##### XML\n```ruby\n  handle_api_errors(format: :xml)\n```\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cError\u003e\n  \u003cTitle\u003eInternal Server Error\u003c/title\u003e\n  \u003cDetail\u003eSomething is very very wrong!\u003c/detail\u003e\n\u003c/Error\u003e\n```\n\n##### Custom Error Responses\nIf none of the out-of-the-box options suit you then you can pass in your own\nerror serializer like so:\n\n```ruby\n  handle_api_errors(serializer: MyCustomErrorSerializer)\n```\n\nThe custom serializer must implement two instance methods, `serialize` and\n`render_format`. The `serialize` method should return the body of the response\nyou want to render. The `render_format` should be the format that you want to\nrender the response in (e.g `:json`, `:xml`, `:plain`), which will be passed to\nRails' `render` method.\n\nIt is recommended you inherit your serializer from\n`ApiErrorHandler::Serializers::BaseSerializer` to gain some helpful instance\nmethods and defaults.\n\n```ruby\nclass MyCustomErrorSerializer \u003c ApiErrorHandler::Serializers::BaseSerializer\n  def serialize(serializer_options)\n    # The `title` and `status_code` come from the BaseSerializer.\n    \"Error! Title: #{title} Status Code: #{status_code}\"\n  end\n\n  def render_format\n    :plain\n  end\nend\n```\n##### Backtraces\nIf you want to include the error's backtrace in the response body:\n\n```ruby\n  handle_api_errors(backtrace: true)\n```\n\n```json\n{\n  \"error\": {\n    \"title\":\"Internal Server Error\",\n    \"detail\":\"Something is very very wrong!\",\n    \"backtrace\": [\n      # The backtrace\n    ]\n  }\n}\n```\n\n### HTTP Status Mapping\n\nMost of the time, you'll want to set the HTTP status code based on the type of\nerror being raised. To determine which errors map to which status codes,\n`api_error_handler` uses `ActionDispatch::ExceptionWrapper.rescue_responses`. If\nyou're using Rails with ActiveRecord, by default this includes:\n\n```ruby\n{\n  \"ActionController::RoutingError\"               =\u003e :not_found,\n  \"AbstractController::ActionNotFound\"           =\u003e :not_found,\n  \"ActionController::MethodNotAllowed\"           =\u003e :method_not_allowed,\n  \"ActionController::UnknownHttpMethod\"          =\u003e :method_not_allowed,\n  \"ActionController::NotImplemented\"             =\u003e :not_implemented,\n  \"ActionController::UnknownFormat\"              =\u003e :not_acceptable,\n  \"Mime::Type::InvalidMimeType\"                  =\u003e :not_acceptable,\n  \"ActionController::MissingExactTemplate\"       =\u003e :not_acceptable,\n  \"ActionController::InvalidAuthenticityToken\"   =\u003e :unprocessable_entity,\n  \"ActionController::InvalidCrossOriginRequest\"  =\u003e :unprocessable_entity,\n  \"ActionDispatch::Http::Parameters::ParseError\" =\u003e :bad_request,\n  \"ActionController::BadRequest\"                 =\u003e :bad_request,\n  \"ActionController::ParameterMissing\"           =\u003e :bad_request,\n  \"Rack::QueryParser::ParameterTypeError\"        =\u003e :bad_request,\n  \"Rack::QueryParser::InvalidParameterError\"     =\u003e :bad_request,\n  \"ActiveRecord::RecordNotFound\"                 =\u003e :not_found,\n  \"ActiveRecord::StaleObjectError\"               =\u003e :conflict,\n  \"ActiveRecord::RecordInvalid\"                  =\u003e :unprocessable_entity,\n  \"ActiveRecord::RecordNotSaved\"                 =\u003e :unprocessable_entity\n}\n```\n- https://guides.rubyonrails.org/configuring.html#configuring-action-dispatch\n\nYou can add to this mapping on an application level by doing the following:\n```ruby\nconfig.action_dispatch.rescue_responses.merge!(\n  \"AuthenticationError\" =\u003e :unauthorized\n)\n```\n\nNow when an you raise an `AuthenticationError` in one of your actions, the\nstatus code of the response will be 401.\n\n### Error IDs\nSometimes it's helpful to include IDs with your error responses so that you can\ncorrelate a specific error with a record in your logs or bug tracking software.\nFor this you can use the `error_id` option.\n\nYou can either use the UUID error strategy\n```ruby\nhandle_api_errors(error_id: :uuid)\n```\n\nOr pass a Proc if you need to do something custom.\n```ruby\nhandle_api_errors(error_id: Proc.new { |error| SecureRandom.uuid })\n```\n\nThese will result in:\n```json\n{\n  \"error\": {\n    \"title\": \"Internal Server Error\",\n    \"detail\": \"Something is very very wrong!\",\n    \"id\": \"4ab520f2-ae33-4539-9371-ea21aada5582\"\n  }\n}\n```\n\n### Error Reporting\nIf you use an external error tracking software like Sentry or Honeybadger, you'll\nwant to report all errors to that service.\n\n#### Out of the Box Error Reporting\nThere are a few supported error reporter options that you can select.\n\n##### Raven/Sentry\n```ruby\nhandle_api_errors(error_reporter: :raven)\n# Or\nhandle_api_errors(error_reporter: :sentry)\n```\n\n##### Honeybadger\n```ruby\nhandle_api_errors(error_reporter: :honeybadger)\n```\n\n__NOTE:__ If you use the `:error_id` option, the error error reporter will tag\nthe exception with the error ID when reporting the error.\n\n#### Custom Reporting\nIf none of the out of the box options work for you, you can pass in a proc which\nwill receive the error and the error_id as arguments.\n\n```ruby\nhandle_api_errors(\n  error_reporter: Proc.new do |error, error_id|\n    # Do something with the `error` here.\n  end\n)\n```\n\n### Setting Content Type\nThe api_error_handler will set the content type of your error based on the\n`format` option you pick. However, you can override this by setting the\n`content_type` option if you wish.\n\n```ruby\nhandle_api_errors(\n  format: :json,\n  content_type: 'application/vnd.api+json'\n)\n```\n\n```json\nHTTP/1.1 500 Internal Server Error\nContent-Type: application/vnd.api+json\n\n{\n  \"error\": {\n    \"title\":\"Internal Server Error\",\n    \"detail\":\"Something is very very wrong!\"\n  }\n}\n```\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamesstonehill%2Fapi_error_handler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamesstonehill%2Fapi_error_handler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamesstonehill%2Fapi_error_handler/lists"}