{"id":16062009,"url":"https://github.com/gsamokovarov/timeout_errors","last_synced_at":"2025-04-05T09:14:41.795Z","repository":{"id":27949466,"uuid":"31442155","full_name":"gsamokovarov/timeout_errors","owner":"gsamokovarov","description":"Catch all of them Net::HTTP timeout errors.","archived":false,"fork":false,"pushed_at":"2015-02-27T22:48:05.000Z","size":128,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-12T04:23:22.690Z","etag":null,"topics":["exceptions","ruby","timeout"],"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/gsamokovarov.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":"2015-02-27T22:34:57.000Z","updated_at":"2019-07-16T07:50:08.000Z","dependencies_parsed_at":"2022-09-04T09:10:43.204Z","dependency_job_id":null,"html_url":"https://github.com/gsamokovarov/timeout_errors","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsamokovarov%2Ftimeout_errors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsamokovarov%2Ftimeout_errors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsamokovarov%2Ftimeout_errors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsamokovarov%2Ftimeout_errors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gsamokovarov","download_url":"https://codeload.github.com/gsamokovarov/timeout_errors/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247312092,"owners_count":20918344,"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":["exceptions","ruby","timeout"],"created_at":"2024-10-09T04:21:23.734Z","updated_at":"2025-04-05T09:14:41.768Z","avatar_url":"https://github.com/gsamokovarov.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Timeout Errors\n\nCatch all of them Net::HTTP timeout errors. Why? Because there are lots of\nthem.\n\n## Install\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'timeout_errors'\n```\n\n## Play\n\nLet's playing a game. You do a request. It times out. You try to guess which\nerror it timed out with. Here's how you win every time.\n\n```ruby\nrequire 'uri'\nrequire 'timeout_errors'\n\nbegin\n  uri = URI.parse(\"http://imsuresomeonewillregisterthatjusttotroll.me/\")\n  Net::HTTP.get_response(uri)\nrescue TimeoutErrors =\u003e e\n  puts \"And the winner is: #{e.inspect}\"\nend\n```\n\nNow, imagine your favourite 3rd party HTTP client library, that uses `net/http`\nunder the hook invents yet another one of those pesky timeout errors. If you\nplay the game with that specific 3rd party library, you are quite likely to\nloose. Here's how you can improve your chances:\n\n```ruby\nrequire 'best_http_client_ever_because_we_need_yet_another_one'\nrequire 'timeout_errors'\n\nTimeoutErrors.include_error(\n  BestHttpClientEverBecauseWeNeedYetAnotherOne::YetAnotherTimeoutToSolveItAllError\n)\n\nbegin\n  BestHttpClientEverBecauseWeNeedYetAnotherOne.get(\n    \"http://imsuresomeonewillregisterthatjusttotroll.me/\"\n  )\nrescue TimeoutErrors =\u003e e\n  puts \"Your favourite timeout error is: #{e.inspect}\"\nend\n```\n\nQuite useful, heh?\n\n## Winners\n\nHere's the list of errors caught by `TimeoutErrors` by default.\n\n- `EOFError`\n- `Errno::ECONNREFUSED`\n- `Errno::ECONNRESET`\n- `Errno::EHOSTUNREACH`\n- `Errno::EINVAL`\n- `Errno::ENETUNREACH`\n- `Errno::EPIPE`\n- `Errno::ETIMEDOUT`\n- `Net::HTTPBadResponse`\n- `Net::HTTPHeaderSyntaxError`\n- `Net::ProtocolError`\n- `SocketError`\n- `Timeout::Error`\n\nNote that you can fill this list during runtime with\n`TimeoutErrors.include_error`.\n\n## Why\n\nThere is a lot of previous art on this topic. Why create another one?\n\n### [net_http_timeout_errors]\n\nThis library is a great choice. It uses standard Ruby interface and clearly\nlists all the errors. However, I wanna catch them all with a single `rescue\nErrorMatcher` clause. Which leads us to [net_http_exception_fix].\n\n### [net_http_exception_fix]\n\n[net_http_exception_fix] is a hotfix to give those common exceptions that pop\nup from Net:HTTP usage a shared parent exception class. This is the interface I\nlike, however it is achieved through polluting builtin' errors ancestor chain.\n\n## How\n\nInstead of introducing extra interface, or monkey patching existing errors,\nthis library exploits a fun little fact about Ruby's exception handling. Errors\nlisted on the `rescue` clause are matched with the case (`===`) operator.\n\n## Credits\n\nThanks to the authors and contributors of [net_http_timeout_errors] and\n[net_http_exception_fix].\n\n[net_http_timeout_errors]: https://github.com/barsoom/net_http_timeout_errors\n[net_http_exception_fix]: https://github.com/edward/net_http_exception_fix\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsamokovarov%2Ftimeout_errors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgsamokovarov%2Ftimeout_errors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsamokovarov%2Ftimeout_errors/lists"}