{"id":13880231,"url":"https://github.com/ankane/safely","last_synced_at":"2025-11-17T14:01:54.919Z","repository":{"id":19616659,"uuid":"22868128","full_name":"ankane/safely","owner":"ankane","description":"Rescue and report exceptions in non-critical code","archived":false,"fork":false,"pushed_at":"2025-05-26T22:22:22.000Z","size":78,"stargazers_count":550,"open_issues_count":1,"forks_count":13,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-11-05T11:08:32.754Z","etag":null,"topics":[],"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/ankane.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-08-12T07:06:36.000Z","updated_at":"2025-10-08T16:46:47.000Z","dependencies_parsed_at":"2023-12-26T20:38:52.605Z","dependency_job_id":"f49758fe-e8e5-4ced-a2c3-233b9d5c539f","html_url":"https://github.com/ankane/safely","commit_stats":{"total_commits":135,"total_committers":6,"mean_commits":22.5,"dds":"0.45925925925925926","last_synced_commit":"7abd163663ca2a0bdc704facead91dc3c16614f8"},"previous_names":["ankane/robustly"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/ankane/safely","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fsafely","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fsafely/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fsafely/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fsafely/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ankane","download_url":"https://codeload.github.com/ankane/safely/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fsafely/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284750955,"owners_count":27057456,"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-11-16T02:00:05.974Z","response_time":65,"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":[],"created_at":"2024-08-06T08:02:52.971Z","updated_at":"2025-11-17T14:01:54.884Z","avatar_url":"https://github.com/ankane.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Safely\n\n```ruby\nsafely do\n  # keep going if this code fails\nend\n```\n\nExceptions are rescued and automatically reported to your favorite reporting service.\n\nIn development and test environments, exceptions are raised so you can fix them.\n\n[Read more](https://ankane.org/safely-pattern)\n\n[![Build Status](https://github.com/ankane/safely/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/safely/actions)\n\n## Installation\n\nAdd this line to your application’s Gemfile:\n\n```ruby\ngem \"safely_block\"\n```\n\n## Use It Everywhere\n\n“Oh no, analytics brought down search”\n\n```ruby\nsafely { track_search(params) }\n```\n\n“Recommendations stopped updating because of one bad user”\n\n```ruby\nusers.each do |user|\n  safely(context: {user_id: user.id}) { update_recommendations(user) }\nend\n```\n\nAlso aliased as `yolo`\n\n## Features\n\nPass extra context to be reported with exceptions\n\n```ruby\nsafely context: {user_id: 123} do\n  # code\nend\n```\n\nSpecify a default value to return on exceptions\n\n```ruby\nshow_banner = safely(default: true) { show_banner_logic }\n```\n\nRaise specific exceptions\n\n```ruby\nsafely except: ActiveRecord::RecordNotUnique do\n  # all other exceptions will be rescued\nend\n```\n\nPass an array for multiple exception classes.\n\nRescue only specific exceptions\n\n```ruby\nsafely only: ActiveRecord::RecordNotUnique do\n  # all other exceptions will be raised\nend\n```\n\nSilence exceptions\n\n```ruby\nsafely silence: ActiveRecord::RecordNotUnique do\n  # code\nend\n```\n\nThrottle reporting with:\n\n```ruby\nsafely throttle: {limit: 10, period: 1.minute} do\n  # reports only first 10 exceptions each minute\nend\n```\n\n**Note:** The throttle limit is approximate and per process.\n\n## Reporting\n\nReports exceptions to a variety of services out of the box.\n\n- [Airbrake](https://airbrake.io/)\n- [Appsignal](https://appsignal.com/)\n- [Bugsnag](https://bugsnag.com/)\n- [Datadog](https://www.datadoghq.com/product/error-tracking/)\n- [Exception Notification](https://github.com/kmcphillips/exception_notification)\n- [Google Stackdriver](https://cloud.google.com/stackdriver/)\n- [Honeybadger](https://www.honeybadger.io/)\n- [New Relic](https://newrelic.com/)\n- [Raygun](https://raygun.io/)\n- [Rollbar](https://rollbar.com/)\n- [Scout APM](https://scoutapm.com/)\n- [Sentry](https://getsentry.com/)\n\n**Note:** Context is not supported with Google Stackdriver and Scout APM\n\nCustomize reporting with:\n\n```ruby\nSafely.report_exception_method = -\u003e(e) { Rollbar.error(e) }\n```\n\nWith Rails, you can add this in an initializer.\n\nBy default, exception messages are prefixed with `[safely]`. This makes it easier to spot rescued exceptions. Turn this off with:\n\n```ruby\nSafely.tag = false\n```\n\nBy default, exceptions are raised in the development and test environments. Change this with:\n\n```ruby\nSafely.raise_envs += [\"staging\"]\n```\n\nTo report exceptions manually:\n\n```ruby\nSafely.report_exception(e)\n```\n\n## Data Protection\n\nTo protect the privacy of your users, do not send [personal data](https://en.wikipedia.org/wiki/Personally_identifiable_information) to exception services. Filter sensitive form fields, use ids (not email addresses) to identify users, and mask IP addresses.\n\nWith Rollbar, you can do:\n\n```ruby\nRollbar.configure do |config|\n  config.person_id_method = \"id\" # default\n  config.scrub_fields |= [:birthday]\n  config.anonymize_user_ip = true\nend\n```\n\nWhile working on exceptions, be on the lookout for personal data and correct as needed.\n\n## History\n\nView the [changelog](https://github.com/ankane/safely/blob/master/CHANGELOG.md)\n\n## Contributing\n\nEveryone is encouraged to help improve this project. Here are a few ways you can help:\n\n- [Report bugs](https://github.com/ankane/safely/issues)\n- Fix bugs and [submit pull requests](https://github.com/ankane/safely/pulls)\n- Write, clarify, or fix documentation\n- Suggest or add new features\n\nTo get started with development and testing:\n\n```sh\ngit clone https://github.com/ankane/safely.git\ncd safely\nbundle install\nbundle exec rake test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankane%2Fsafely","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fankane%2Fsafely","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankane%2Fsafely/lists"}