Пример #1
0
 invites.forEach((invite) => {
     if (invite.success) {
         successCount += 1;
     } else if (isInvalidError(invite.error)) {
         message = `${invite.email} was invalid: ${invite.error.payload.errors[0].message}`;
         notifications.showAlert(message, {type: 'error', delayed: true, key: `signup.send-invitations.${invite.email}`});
     } else {
         erroredEmails.push(invite.email);
     }
 });
Пример #2
0
    sendTestNotification: task(function* () {
        let notifications = this.notifications;
        let slackApi = this.get('ghostPaths.url').api('slack', 'test');

        try {
            yield this.save.perform();
            yield this.ajax.post(slackApi);
            notifications.showNotification('Check your Slack channel for the test message!', {type: 'info', key: 'slack-test.send.success'});
            return true;
        } catch (error) {
            notifications.showAPIError(error, {key: 'slack-test:send'});

            if (!isInvalidError(error)) {
                throw error;
            }
        }
    }).drop()
            }).catch((error) => {
                // re-throw if we have a general server error
                if (error && !isInvalidError(error)) {
                    this.toggleProperty('submitting');
                    this.send('error', error);
                    return;
                }

                if (!options.silent) {
                    error = error || this.get('model.errors.messages');
                    this.showErrorAlert(prevStatus, this.get('model.status'), error);
                }

                this.set('model.status', prevStatus);

                this.toggleProperty('submitting');
                return this.get('model');
            });
Пример #4
0
            }).catch((error) => {
                // TODO: server-side validation errors should be serialized
                // properly so that errors are added to the model's errors
                // property
                if (error && isInvalidError(error)) {
                    let [firstError] = error.errors;
                    let {message} = firstError;

                    if (message && message.match(/email/i)) {
                        this.get('model.errors').add('email', message);
                        this.get('model.hasValidated').pushObject('email');
                        return;
                    }
                }

                // this is a route action so it should bubble up to the global
                // error handler
                throw error;
            }).finally(() => {
Пример #5
0
    addSubscriber: task(function* () {
        try {
            yield this.get('confirm')();
            this.send('closeModal');
        } catch (error) {
            // TODO: server-side validation errors should be serialized
            // properly so that errors are added to model.errors automatically
            if (error && isInvalidError(error)) {
                let [firstError] = error.errors;
                let {message} = firstError;

                if (message && message.match(/email/i)) {
                    this.get('model.errors').add('email', message);
                    this.get('model.hasValidated').pushObject('email');
                    return;
                }
            }

            // route action so it should bubble up to the global error handler
            if (error) {
                throw error;
            }
        }
    }).drop(),
Пример #6
0
    createIntegration: task(function* () {
        try {
            let integration = yield this.confirm();
            this.router.transitionTo('settings.integration', integration);
        } catch (error) {
            // TODO: server-side validation errors should be serialized
            // properly so that errors are added to model.errors automatically
            if (error && isInvalidError(error)) {
                let [firstError] = error.payload.errors;
                let {message} = firstError;

                if (message && message.match(/name/i)) {
                    this.get('integration.errors').add('name', message);
                    this.get('integration.hasValidated').pushObject('name');
                    return;
                }
            }

            // bubble up to the global error handler
            if (error) {
                throw error;
            }
        }
    }).drop()
Пример #7
0
 it('isInvalidError: detects error class correctly', function() {
   const error = new InvalidError();
   ok(isInvalidError(error));
 });
Пример #8
0
 it('isInvalidError: detects error code correctly', function() {
   ok(isInvalidError(422));
 });
Пример #9
0
                    return this._afterAuthentication(result);
                }).catch((error) => {
                    this._handleAuthenticationError(error);
                }).finally(() => {
                    this.set('session.skipAuthSuccessHandler', undefined);
                });
            }).catch((error) => {
                this._handleSaveError(error);
            });
        }).catch(() => {
            this.set('flowErrors', 'Please fill out the form to setup your blog.');
        });
    },

    _handleSaveError(resp) {
        if (isInvalidError(resp)) {
            let [error] = resp.payload.errors;
            this.set('flowErrors', [error.message, error.context].join(' '));
        } else {
            this.notifications.showAPIError(resp, {key: 'setup.blog-details'});
        }
    },

    _handleAuthenticationError(error) {
        if (error && error.payload && error.payload.errors) {
            let [apiError] = error.payload.errors;
            this.set('flowErrors', [apiError.message, apiError.context].join(' '));
        } else {
            // Connection errors don't return proper status message, only req.body
            this.notifications.showAlert('There was a problem on the server.', {type: 'error', key: 'setup.authenticate.failed'});
        }
Пример #10
0
    save: task(function* (options = {}) {
        let prevStatus = this.get('post.status');
        let isNew = this.get('post.isNew');
        let status;

        this.send('cancelAutosave');

        if (options.backgroundSave && !this.get('hasDirtyAttributes')) {
            return;
        }

        if (options.backgroundSave) {
            // do not allow a post's status to be set to published by a background save
            status = 'draft';
        } else {
            if (this.get('post.pastScheduledTime')) {
                status = (!this.get('willSchedule') && !this.get('willPublish')) ? 'draft' : 'published';
            } else {
                if (this.get('willPublish') && !this.get('post.isScheduled')) {
                    status = 'published';
                } else if (this.get('willSchedule') && !this.get('post.isPublished')) {
                    status = 'scheduled';
                } else {
                    status = 'draft';
                }
            }
        }

        // ensure we remove any blank cards when performing a full save
        if (!options.backgroundSave) {
            if (this._koenig) {
                this._koenig.cleanup();
                this.set('hasDirtyAttributes', true);
            }
        }

        // Set the properties that are indirected
        // set mobiledoc equal to what's in the editor but create a copy so that
        // nested objects/arrays don't keep references which can mean that both
        // scratch and mobiledoc get updated simultaneously
        this.set('post.mobiledoc', copy(this.get('post.scratch'), true));
        this.set('post.status', status);

        // Set a default title
        if (!this.get('post.titleScratch').trim()) {
            this.set('post.titleScratch', DEFAULT_TITLE);
        }

        this.set('post.title', this.get('post.titleScratch'));
        this.set('post.customExcerpt', this.get('post.customExcerptScratch'));
        this.set('post.footerInjection', this.get('post.footerExcerptScratch'));
        this.set('post.headerInjection', this.get('post.headerExcerptScratch'));
        this.set('post.metaTitle', this.get('post.metaTitleScratch'));
        this.set('post.metaDescription', this.get('post.metaDescriptionScratch'));
        this.set('post.ogTitle', this.get('post.ogTitleScratch'));
        this.set('post.ogDescription', this.get('post.ogDescriptionScratch'));
        this.set('post.twitterTitle', this.get('post.twitterTitleScratch'));
        this.set('post.twitterDescription', this.get('post.twitterDescriptionScratch'));

        if (!this.get('post.slug')) {
            this.get('saveTitle').cancelAll();

            yield this.get('generateSlug').perform();
        }

        try {
            let post = yield this.get('post').save(options);

            if (!options.silent) {
                this._showSaveNotification(prevStatus, post.get('status'), isNew ? true : false);
            }

            this.get('post').set('statusScratch', null);

            // redirect to edit route if saving a new record
            if (isNew && post.get('id')) {
                if (!this.get('leaveEditorTransition')) {
                    this.replaceRoute('editor.edit', post);
                }
                return true;
            }

            return post;
        } catch (error) {
            // re-throw if we have a general server error
            if (error && !isInvalidError(error)) {
                this.send('error', error);
                return;
            }

            this.set('post.status', prevStatus);

            if (!options.silent) {
                let errorOrMessages = error || this.get('post.errors.messages');
                this._showErrorAlert(prevStatus, this.get('post.status'), errorOrMessages);
                // simulate a validation error for upstream tasks
                throw undefined;
            }

            return this.get('post');
        }
    }).group('saveTasks'),