{"action":"closed","issue":{"url":"https://api.github.com/repos/TryGhost/Ghost/issues/2118","labels_url":"https://api.github.com/repos/TryGhost/Ghost/issues/2118/labels{/name}","comments_url":"https://api.github.com/repos/TryGhost/Ghost/issues/2118/comments","events_url":"https://api.github.com/repos/TryGhost/Ghost/issues/2118/events","html_url":"https://github.com/TryGhost/Ghost/issues/2118","id":26873107,"number":2118,"title":"Handle errors from apps appropriately","user":{"login":"ErisDS","id":101513,"avatar_url":"https://avatars.githubusercontent.com/u/101513?v=3","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/TryGhost/Ghost/labels/apps","name":"apps","color":"c7def8"},{"url":"https://api.github.com/repos/TryGhost/Ghost/labels/later","name":"later","color":"eaeaea"},{"url":"https://api.github.com/repos/TryGhost/Ghost/labels/server","name":"server","color":"0B939C"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2014-02-04T10:50:21Z","updated_at":"2015-06-26T11:54:10Z","closed_at":"2015-06-26T11:54:10Z","body":"It's not going to be possible to close this until pretty late in 0.5, but I hope that having this written out will mean that expectations are clear, and we might not have to do any additional work for this issue.\r\n\r\nFirstly, starting Ghost with a non-existent apps defined in either activeApps or installedApps needs to result in a nicely formatted red-white-green error message output to the console, but no crash and no unhandled promise errors in dev mode. Apps which don't exist simply don't get loaded into Ghost, and the App UI will deal with messaging this in a more friendly way and providing options to resolve the problem.\r\n\r\nSecondly, errors in apps also need to result in sensible behaviour - again a nicely formatted red-white-green error message on the console, absolutely no crashing or unhandled promise rejections coming from Ghost itself. If an app throws / causes an error during it's initial activation or loading then don't load the app at all. If the error is caused later, handle the error as best as possible.\r\n\r\nWhere possible we might want to consider deactivating an app that causes errors. Especially if those errors appear in a key place such as on the app management screen, as if this was to show a 500 error page, the user would be prevented from disabling a broken app.\r\n\r\nSome errors that might happen in apps:\r\n\r\n- syntax errors in JavaScript\r\n- typos / attempts to use APIs that don't exist or don't make sense in a given context\r\n- attempts to do things that apps are not meant to do\r\n- destructive actions - an app might delete stuff it depends upon\r\n- problematic / missing dependencies in apps\r\n- any errors of any kind with package.json files\r\n\r\nEssentially, we have no way to guarantee the quality of code in an app, it may well break, and we need to be ready for that.\r\n"}}