{"action":"created","issue":{"url":"https://api.github.com/repos/dimagi/commcare-hq/issues/6126","labels_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/6126/labels{/name}","comments_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/6126/comments","events_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/6126/events","html_url":"https://github.com/dimagi/commcare-hq/pull/6126","id":65517984,"number":6126,"title":"Add soft_assert utility","user":{"login":"dannyroberts","id":137212,"avatar_url":"https://avatars.githubusercontent.com/u/137212?v=3","gravatar_id":"","url":"https://api.github.com/users/dannyroberts","html_url":"https://github.com/dannyroberts","followers_url":"https://api.github.com/users/dannyroberts/followers","following_url":"https://api.github.com/users/dannyroberts/following{/other_user}","gists_url":"https://api.github.com/users/dannyroberts/gists{/gist_id}","starred_url":"https://api.github.com/users/dannyroberts/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dannyroberts/subscriptions","organizations_url":"https://api.github.com/users/dannyroberts/orgs","repos_url":"https://api.github.com/users/dannyroberts/repos","events_url":"https://api.github.com/users/dannyroberts/events{/privacy}","received_events_url":"https://api.github.com/users/dannyroberts/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dimagi/commcare-hq/labels/up%20for%20grabs","name":"up for grabs","color":"207de5"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-03-31T18:37:36Z","updated_at":"2015-03-31T21:23:19Z","closed_at":"2015-03-31T21:18:47Z","pull_request":{"url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/6126","html_url":"https://github.com/dimagi/commcare-hq/pull/6126","diff_url":"https://github.com/dimagi/commcare-hq/pull/6126.diff","patch_url":"https://github.com/dimagi/commcare-hq/pull/6126.patch"},"body":"And use it to (soft) assert timezones are not strings.\r\n\r\nThe use case for soft assert is when you think something shouldn't be happening and you want to see where in production, if at all, it's happening. When you add a `soft_assert` to your code, you pass in your own email as a parameter, and every time your assumption is violated, you'll get an email with the traceback, and the number of times it's happened so far, with an exponential back-off so you only get emailed the 1st, 2nd, 4th, 8th, 16th, etc. time that the same error happens. Two errors are considered the same if the last two frames of the stack output (the one where you called soft_assert and then previous one) are identical. This means that if two functions call the same function, and that function uses `soft_assert` there will be one \"thread\" for each of those two functions. This helps you see all of the separate places from which your function is called \"incorrectly\".\r\n\r\nLooks something like this in your inbox. (Except that now there's going to be \"[production] \" (or whatever) prefixed to the subject.)\r\n\r\n![screen shot 2015-03-31 at 4 40 16 pm](https://cloud.githubusercontent.com/assets/137212/6928842/cde389d8-d7c4-11e4-8894-805cbe956f4e.png)\r\n"},"comment":{"url":"https://api.github.com/repos/dimagi/commcare-hq/issues/comments/88254783","html_url":"https://github.com/dimagi/commcare-hq/pull/6126#issuecomment-88254783","issue_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/6126","id":88254783,"user":{"login":"dannyroberts","id":137212,"avatar_url":"https://avatars.githubusercontent.com/u/137212?v=3","gravatar_id":"","url":"https://api.github.com/users/dannyroberts","html_url":"https://github.com/dannyroberts","followers_url":"https://api.github.com/users/dannyroberts/followers","following_url":"https://api.github.com/users/dannyroberts/following{/other_user}","gists_url":"https://api.github.com/users/dannyroberts/gists{/gist_id}","starred_url":"https://api.github.com/users/dannyroberts/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dannyroberts/subscriptions","organizations_url":"https://api.github.com/users/dannyroberts/orgs","repos_url":"https://api.github.com/users/dannyroberts/repos","events_url":"https://api.github.com/users/dannyroberts/events{/privacy}","received_events_url":"https://api.github.com/users/dannyroberts/received_events","type":"User","site_admin":false},"created_at":"2015-03-31T21:23:19Z","updated_at":"2015-03-31T21:23:19Z","body":":tada: "}}