From 3c92c171f9507f13fccf819c18a17f8b5c02b2b9 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Fri, 8 Jul 2016 14:54:36 +0100 Subject: [PATCH] "503 Maintenance" error handling refs https://github.com/TryGhost/Ghost/issues/6976 - adds custom `MaintenanceError` and associated error checking functions - updates app route and notifications service to handle `503` errors via the `upgrade-status` service --- ghost/admin/app/mirage/config.js | 8 ++++++++ ghost/admin/app/routes/application.js | 8 ++++++++ ghost/admin/app/services/ajax.js | 24 ++++++++++++++++++++++ ghost/admin/app/services/notifications.js | 8 +++++++- ghost/admin/app/services/upgrade-status.js | 7 +++++++ 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/ghost/admin/app/mirage/config.js b/ghost/admin/app/mirage/config.js index e79ff78bf8..4c20e6dc44 100644 --- a/ghost/admin/app/mirage/config.js +++ b/ghost/admin/app/mirage/config.js @@ -9,6 +9,14 @@ const { } = Ember; /* jshint unused:false */ +function maintenanceResponse() { + return new Mirage.Response(503, {}, { + errors: [{ + errorType: 'Maintenance' + }] + }); +} + function versionMismatchResponse() { return new Mirage.Response(400, {}, { errors: [{ diff --git a/ghost/admin/app/routes/application.js b/ghost/admin/app/routes/application.js index f433143137..4fa748e2a6 100644 --- a/ghost/admin/app/routes/application.js +++ b/ghost/admin/app/routes/application.js @@ -176,6 +176,14 @@ export default Route.extend(ApplicationRouteMixin, ShortcutsRoute, { this.get('upgradeStatus').requireUpgrade(); return false; + case 'Maintenance': + if (transition) { + transition.abort(); + } + + this.get('upgradeStatus').maintenanceAlert(); + return false; + default: this.get('notifications').showAPIError(error); // don't show the 500 page if we weren't navigating diff --git a/ghost/admin/app/services/ajax.js b/ghost/admin/app/services/ajax.js index c5e38e2d3d..6929054da0 100644 --- a/ghost/admin/app/services/ajax.js +++ b/ghost/admin/app/services/ajax.js @@ -70,6 +70,24 @@ export function isUnsupportedMediaTypeError(errorOrStatus) { } } +/* Maintenance error */ + +export function MaintenanceError(errors) { + AjaxError.call(this, errors, 'Ghost is currently undergoing maintenance, please wait a moment then retry.'); +} + +MaintenanceError.prototype = Object.create(AjaxError.prototype); + +export function isMaintenanceError(errorOrStatus) { + if (isAjaxError(errorOrStatus)) { + return errorOrStatus instanceof MaintenanceError; + } else if (errorOrStatus && get(errorOrStatus, 'isAdapterError')) { + return get(errorOrStatus, 'errors.firstObject.errorType') === 'Maintenance'; + } else { + return errorOrStatus === 503; + } +} + /* end: custom error types */ export default AjaxService.extend({ @@ -99,6 +117,8 @@ export default AjaxService.extend({ return new RequestEntityTooLargeError(payload.errors); } else if (this.isUnsupportedMediaTypeError(status, headers, payload)) { return new UnsupportedMediaTypeError(payload.errors); + } else if (this.isMaintenanceError(status, headers, payload)) { + return new MaintenanceError(payload.errors); } return this._super(...arguments); @@ -136,5 +156,9 @@ export default AjaxService.extend({ isUnsupportedMediaTypeError(status/*, headers, payload */) { return isUnsupportedMediaTypeError(status); + }, + + isMaintenanceError(status, headers, payload) { + return isMaintenanceError(status, payload); } }); diff --git a/ghost/admin/app/services/notifications.js b/ghost/admin/app/services/notifications.js index e7078719d3..f5b8232d7e 100644 --- a/ghost/admin/app/services/notifications.js +++ b/ghost/admin/app/services/notifications.js @@ -4,9 +4,12 @@ import {A as emberA, isEmberArray} from 'ember-array/utils'; import get from 'ember-metal/get'; import set from 'ember-metal/set'; import injectService from 'ember-service/inject'; -import {isVersionMismatchError} from 'ghost-admin/services/ajax'; import {isBlank} from 'ember-utils'; import {dasherize} from 'ember-string'; +import { + isMaintenanceError, + isVersionMismatchError +} from 'ghost-admin/services/ajax'; // Notification keys take the form of "noun.verb.message", eg: // @@ -88,6 +91,9 @@ export default Service.extend({ // handle "global" errors if (isVersionMismatchError(resp)) { return this.get('upgradeStatus').requireUpgrade(); + } else if (isMaintenanceError(resp)) { + console.log(this.get('upgradeStatus')); + return this.get('upgradeStatus').maintenanceAlert(); } // loop over Ember Data / ember-ajax errors object diff --git a/ghost/admin/app/services/upgrade-status.js b/ghost/admin/app/services/upgrade-status.js index 76a7822c6c..c9e3a43486 100644 --- a/ghost/admin/app/services/upgrade-status.js +++ b/ghost/admin/app/services/upgrade-status.js @@ -6,6 +6,13 @@ export default Service.extend({ notifications: injectService(), + maintenanceAlert() { + this.get('notifications').showAlert( + 'Sorry, Ghost is currently undergoing maintenance, please wait a moment then try again.', + {type: 'error', key: 'api-error.under-maintenance'} + ); + }, + requireUpgrade() { this.set('isRequired', true); this.get('notifications').showAlert(