{"action":"created","issue":{"url":"https://api.github.com/repos/tapjs/tap-parser/issues/34","repository_url":"https://api.github.com/repos/tapjs/tap-parser","labels_url":"https://api.github.com/repos/tapjs/tap-parser/issues/34/labels{/name}","comments_url":"https://api.github.com/repos/tapjs/tap-parser/issues/34/comments","events_url":"https://api.github.com/repos/tapjs/tap-parser/issues/34/events","html_url":"https://github.com/tapjs/tap-parser/issues/34","id":170091457,"number":34,"title":"Dropped exceptions in assert event handlers","user":{"login":"jtlapp","id":138133,"avatar_url":"https://avatars.githubusercontent.com/u/138133?v=3","gravatar_id":"","url":"https://api.github.com/users/jtlapp","html_url":"https://github.com/jtlapp","followers_url":"https://api.github.com/users/jtlapp/followers","following_url":"https://api.github.com/users/jtlapp/following{/other_user}","gists_url":"https://api.github.com/users/jtlapp/gists{/gist_id}","starred_url":"https://api.github.com/users/jtlapp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jtlapp/subscriptions","organizations_url":"https://api.github.com/users/jtlapp/orgs","repos_url":"https://api.github.com/users/jtlapp/repos","events_url":"https://api.github.com/users/jtlapp/events{/privacy}","received_events_url":"https://api.github.com/users/jtlapp/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-08-09T06:28:37Z","updated_at":"2016-08-09T22:59:56Z","closed_at":null,"body":"This is curious. When the handler for an 'assert' event throws an exception, `tap-parser` does not immediately throw an exception. Instead, it emits this exception in the next 'assert' event, naming the assertion as the `toString()` of the exception. `tap-parser` only itself throws an exception if this next call to the 'assert' handler again throws an exception. There is also at least one scenario where `tap-parser` neither propagates the exception nor emits 'complete'.\r\n\r\nCase 1: The test contains a single passing assertion for which the 'assert' handler throws an exception. Result: `tap-parser` swallows the exception and quietly terminates without issuing a 'complete'.\r\n\r\nCase 2: The test contains two passing assertions and the 'assert' handler throws an exception only on its first call. Result: `tap-parser` emits 'assert' again, setting `assert.name` to `error.toString()`. The 2nd assertion is never tested and `tap-parser` emits a 'complete'.\r\n\r\nCase 3: The test contains two passing assertions and the 'assert' handler throws an exception on its 1st and 2nd call. Result: The 2nd 'assert' event has `assert.name` set to `error.toString()`, and `tap-parser` terminates with an exception, without emitting a 'complete'.\r\n\r\nCase 4: The test contains a single failing assertion for which the 'assert' handler throws an exception. Result: `tap-parser` emits 'assert' again, setting `assert.name` to `error.toString()`. If there are any subsequent assertions, they are not run. `tap-parser` emits a 'complete'. \r\n\r\nCase 5: The test contains a failing assertion and at least one following assertion. The first two calls to the 'assert' handler throw an exception. Result: The 2nd 'assert' event has `assert.name` set to `error.toString()`, and `tap-parser` terminates with an exception, without emitting a 'complete'. (Same result as case 3.)\r\n\r\nIt seems to me that if an event handler ever throws an exception, `tap-parser` should terminate with an exception. If the 'assert' event handler is expected to construct and throw an exception from the provided exception-generated `assert` object, we still have at least one scenario where the `tap-parser` quietly swallows the exception (case 1)."},"comment":{"url":"https://api.github.com/repos/tapjs/tap-parser/issues/comments/238718265","html_url":"https://github.com/tapjs/tap-parser/issues/34#issuecomment-238718265","issue_url":"https://api.github.com/repos/tapjs/tap-parser/issues/34","id":238718265,"user":{"login":"isaacs","id":9287,"avatar_url":"https://avatars.githubusercontent.com/u/9287?v=3","gravatar_id":"","url":"https://api.github.com/users/isaacs","html_url":"https://github.com/isaacs","followers_url":"https://api.github.com/users/isaacs/followers","following_url":"https://api.github.com/users/isaacs/following{/other_user}","gists_url":"https://api.github.com/users/isaacs/gists{/gist_id}","starred_url":"https://api.github.com/users/isaacs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/isaacs/subscriptions","organizations_url":"https://api.github.com/users/isaacs/orgs","repos_url":"https://api.github.com/users/isaacs/repos","events_url":"https://api.github.com/users/isaacs/events{/privacy}","received_events_url":"https://api.github.com/users/isaacs/received_events","type":"User","site_admin":false},"created_at":"2016-08-09T22:59:56Z","updated_at":"2016-08-09T22:59:56Z","body":"ah, yeah, that's a relic.  Updated in dc7041514b123fc18118ccd7cadceb6225781ba6 to use tap everywhere instead, since it's functionally equivalent and just saves a dep."}}
{"actor":{"display_login":"isaacs"}}