{"action":"created","issue":{"url":"https://api.github.com/repos/autopkg/autopkg/issues/147","labels_url":"https://api.github.com/repos/autopkg/autopkg/issues/147/labels{/name}","comments_url":"https://api.github.com/repos/autopkg/autopkg/issues/147/comments","events_url":"https://api.github.com/repos/autopkg/autopkg/issues/147/events","html_url":"https://github.com/autopkg/autopkg/pull/147","id":57087325,"number":147,"title":"Make run_recipes() except block handle failures more broadly.","user":{"login":"sheagcraig","id":3568072,"avatar_url":"https://avatars.githubusercontent.com/u/3568072?v=3","gravatar_id":"","url":"https://api.github.com/users/sheagcraig","html_url":"https://github.com/sheagcraig","followers_url":"https://api.github.com/users/sheagcraig/followers","following_url":"https://api.github.com/users/sheagcraig/following{/other_user}","gists_url":"https://api.github.com/users/sheagcraig/gists{/gist_id}","starred_url":"https://api.github.com/users/sheagcraig/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sheagcraig/subscriptions","organizations_url":"https://api.github.com/users/sheagcraig/orgs","repos_url":"https://api.github.com/users/sheagcraig/repos","events_url":"https://api.github.com/users/sheagcraig/events{/privacy}","received_events_url":"https://api.github.com/users/sheagcraig/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":17,"created_at":"2015-02-09T20:47:16Z","updated_at":"2015-02-11T14:14:17Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/autopkg/autopkg/pulls/147","html_url":"https://github.com/autopkg/autopkg/pull/147","diff_url":"https://github.com/autopkg/autopkg/pull/147.diff","patch_url":"https://github.com/autopkg/autopkg/pull/147.patch"},"body":"# Exception handling during multiple recipe runs\r\nWhen running a single recipe, a recipe failure is either handled by the individual failing processor and passed up as a ProcessorError and AutoPkg reports a failure, or AutoPkg stops with an exception. Either way, one recipe failed, and you get immediate information about it.\r\n\r\nHowever, when running multiple recipes, an unhandled exception halts AutoPkg execution, rather than continuing with the next recipe. This *should* only be a problem with custom processors, but in practice, and as non standard-library processors (included in recipe repos?) proliferate, those which don't look for exceptions and in-turn raise ```ProcessorError``` have the potential to halt multiple-recipe runs.\r\n\r\nThis isn't a huge problem, but it does prevent the final reporting from happening. When running a long list of recipes that could take a significant period of time, if one recipe failed, I want to know what *else* happened: which new products were downloaded, uploaded to Munki, etc, as well as the failure.\r\n\r\nOne could argue that *any* error should halt AutoPkg if it isn't handled. I know that personally I want an individual recipe error to *not* stop execution, but I guess that depends on how severe the consequences would be for different organizations. (I don't see any...)\r\n\r\nThe wiki could include some information about making sure to wrap failure-prone sections with a try/except that percolates a ProcessorError up, but that seems to be beyond the scope of the standard expectations of an AutoPkg user or recipe-author.\r\n\r\nIt would be nice if the individual processors all handle this, but in practice, some higher level insurance seems appropriate. \r\n\r\n# CTRL-C Handling\r\nIt appears that a lot of the std-lib processors are checking for ```BaseException```, which is the base class for *all* exceptions, including the CTRL-C/```KeyboardInterrupt``` exception. Therefore, during a multiple-recipe ```autopkg run```, some processors will just fail and continue with the next recipe, whereas those without the \r\n```\r\nexcept BaseException as e:\r\n\traise ProcessorError()\r\n```\r\nidiom will stop AutoPkg execution. I think it's safe to assume that CTRL-C should make everything stop, no matter what.\r\n\r\nIf you'd like me to go through stdlib processors and switch them to use ```Exception``` instead of ```BaseException``` to make CTRL-C handling consistent, let me know and I'll update the PR.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/autopkg/autopkg/issues/comments/73886733","html_url":"https://github.com/autopkg/autopkg/pull/147#issuecomment-73886733","issue_url":"https://api.github.com/repos/autopkg/autopkg/issues/147","id":73886733,"user":{"login":"sheagcraig","id":3568072,"avatar_url":"https://avatars.githubusercontent.com/u/3568072?v=3","gravatar_id":"","url":"https://api.github.com/users/sheagcraig","html_url":"https://github.com/sheagcraig","followers_url":"https://api.github.com/users/sheagcraig/followers","following_url":"https://api.github.com/users/sheagcraig/following{/other_user}","gists_url":"https://api.github.com/users/sheagcraig/gists{/gist_id}","starred_url":"https://api.github.com/users/sheagcraig/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sheagcraig/subscriptions","organizations_url":"https://api.github.com/users/sheagcraig/orgs","repos_url":"https://api.github.com/users/sheagcraig/repos","events_url":"https://api.github.com/users/sheagcraig/events{/privacy}","received_events_url":"https://api.github.com/users/sheagcraig/received_events","type":"User","site_admin":false},"created_at":"2015-02-11T14:14:17Z","updated_at":"2015-02-11T14:14:17Z","body":"I dropped back to the last upstream commit and redid this.\r\n\r\n@timsutton At one point I had a multiple try/except/except, i.e.\r\n\r\n```\r\ntry:\r\n\tprocessor.process()\r\nexcept ProcessorError as err:\r\n\t# ...\r\nexcept Exception as err:\r\n\t# ...\r\n```\r\nBut the handling ended up being the same, so I settled on catching ```Exception``` and documenting the reason why it was so broad.\r\n\r\nAlso, I added the traceback to the failure dictionary. I tried adding it into the final reporting, but as you can imagine, the traceback is potentially a lot of mess to add in. I tried it several ways; indenting it another level, etc, and it always seemed wrong. So at the moment it just gets stored. I can address outputting that (possibly with a higher verbosity level?) with the reporting work I'm doing on another branch.\r\n\r\nYou have to grab the traceback while it is being handled. In py3 the exception itself has a ```__traceback__``` property, but py2's ```sys.last_traceback``` gets deleted after handling occurs."}}