mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 12:21:36 +03:00
Added separate "published but email failed" state to publish flow
refs https://github.com/TryGhost/Team/issues/1587 - if post creation succeeds but the email fails to send we want to show a separate state of the publish flow rather than adding an error to the confirm step - confirm _has_ completed so showing the error there doesn't make sense and causes confusing copy - added check for email failure to the `<PublishFlow>` save task (which is called by the confirm step) to intercept any email failure errors and switch state
This commit is contained in:
parent
d353f5dff1
commit
dd3d84a8a5
@ -4,7 +4,7 @@
|
||||
<span>{{svg-jar "arrow-left"}} Editor</span>
|
||||
</button>
|
||||
|
||||
{{#unless this.isComplete}}
|
||||
{{#if (and (not this.emailErrorMessage) (not this.isComplete))}}
|
||||
<div class="flex">
|
||||
<div>
|
||||
<button
|
||||
@ -20,11 +20,18 @@
|
||||
</button>
|
||||
<div class="settings-menu-toggle-spacer"></div>
|
||||
</div>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</header>
|
||||
|
||||
<div class="gh-publish-settings-container">
|
||||
{{#if this.isConfirming}}
|
||||
{{#if this.emailErrorMessage}}
|
||||
<EditorLabs::Modals::PublishFlow::CompleteWithEmailError
|
||||
@emailErrorMessage={{this.emailErrorMessage}}
|
||||
@publishOptions={{@data.publishOptions}}
|
||||
@posCount={{this.posCount}}
|
||||
@close={{@close}}
|
||||
/>
|
||||
{{else if this.isConfirming}}
|
||||
<EditorLabs::Modals::PublishFlow::Confirm
|
||||
@publishOptions={{@data.publishOptions}}
|
||||
@recipientType={{this.recipientType}}
|
||||
|
@ -13,6 +13,7 @@ export default class PublishModalComponent extends Component {
|
||||
|
||||
@service store;
|
||||
|
||||
@tracked emailErrorMessage;
|
||||
@tracked isConfirming = false;
|
||||
@tracked isComplete = false;
|
||||
@tracked postCount = null;
|
||||
@ -50,10 +51,18 @@ export default class PublishModalComponent extends Component {
|
||||
|
||||
@task
|
||||
*saveTask() {
|
||||
yield this.args.data.saveTask.perform();
|
||||
try {
|
||||
yield this.args.data.saveTask.perform();
|
||||
|
||||
this.isConfirming = false;
|
||||
this.isComplete = true;
|
||||
this.isConfirming = false;
|
||||
this.isComplete = true;
|
||||
} catch (e) {
|
||||
if (e?.name === 'EmailFailedError') {
|
||||
return this.emailErrorMessage = e.message;
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// we fetch the new post count in advance when reaching the confirm step
|
||||
|
@ -0,0 +1,46 @@
|
||||
{{#let @publishOptions.post as |post|}}
|
||||
<div class="gh-publish-title">
|
||||
<span class="green">Boom. It’s out there.</span>
|
||||
|
||||
{{#if post.emailOnly}}
|
||||
Your email has been created.
|
||||
{{else if (and post.isPost @postCount)}}
|
||||
That’s {{@postCount}} posts published, keep going!
|
||||
{{else}}
|
||||
Your {{post.displayName}} has been published.
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<p class="error gh-box gh-box-error mt3 mb3">
|
||||
{{svg-jar "warning"}}
|
||||
|
||||
{{#if @publishOptions.willOnlyEmail}}
|
||||
Your post has been created but the email failed to send.
|
||||
{{else}}
|
||||
Your post has been published but the email failed to send.
|
||||
{{/if}}
|
||||
|
||||
Please verify your email settings if the error persists.
|
||||
<br><br>
|
||||
Email error: {{this.emailErrorMessage}}
|
||||
</p>
|
||||
|
||||
{{#if this.retryErrorMessage}}
|
||||
<p class="error gh-box gh-box-error mt3 mb3">
|
||||
{{svg-jar "warning"}}
|
||||
{{this.retryErrorMessage}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
<div class="gh-publish-cta">
|
||||
<GhTaskButton
|
||||
@task={{this.retryEmailTask}}
|
||||
@buttonText="Retry sending email"
|
||||
@runningText="Sending"
|
||||
@successText="Sent"
|
||||
@class="gh-btn gh-btn-large"
|
||||
@showIcon={{false}}
|
||||
/>
|
||||
</div>
|
||||
{{/let}}
|
||||
|
@ -0,0 +1,71 @@
|
||||
import Component from '@glimmer/component';
|
||||
import EmailFailedError from 'ghost-admin/errors/email-failed-error';
|
||||
import {CONFIRM_EMAIL_MAX_POLL_LENGTH, CONFIRM_EMAIL_POLL_LENGTH} from '../../publish-management';
|
||||
import {htmlSafe} from '@ember/template';
|
||||
import {isServerUnreachableError} from 'ghost-admin/services/ajax';
|
||||
import {task, timeout} from 'ember-concurrency';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
function isString(str) {
|
||||
return toString.call(str) === '[object String]';
|
||||
}
|
||||
|
||||
export default class PublishFlowCompleteWithEmailError extends Component {
|
||||
@tracked newEmailErrorMessage;
|
||||
@tracked retryErrorMessage;
|
||||
|
||||
get emailErrorMessage() {
|
||||
return this.newEmailErrorMessage || this.args.emailErrorMessage;
|
||||
}
|
||||
|
||||
@task({drop: true})
|
||||
*retryEmailTask() {
|
||||
this.retryErrorMessage = null;
|
||||
|
||||
try {
|
||||
let email = yield this.args.publishOptions.post.email.retry();
|
||||
|
||||
let pollTimeout = 0;
|
||||
if (email && email.status !== 'submitted') {
|
||||
while (pollTimeout < CONFIRM_EMAIL_MAX_POLL_LENGTH) {
|
||||
yield timeout(CONFIRM_EMAIL_POLL_LENGTH);
|
||||
pollTimeout += CONFIRM_EMAIL_POLL_LENGTH;
|
||||
|
||||
email = yield email.reload();
|
||||
|
||||
if (email.status === 'submitted') {
|
||||
break;
|
||||
}
|
||||
if (email.status === 'failed') {
|
||||
throw new EmailFailedError(email.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return email;
|
||||
} catch (e) {
|
||||
// update "failed" state if email fails again
|
||||
if (e && e.name === 'EmailFailedError') {
|
||||
this.newEmailErrorMessage = e.message;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
let errorMessage = '';
|
||||
|
||||
if (isServerUnreachableError(e)) {
|
||||
errorMessage = 'Unable to connect, please check your internet connection and try again.';
|
||||
} else if (e && isString(e)) {
|
||||
errorMessage = e;
|
||||
} else if (e?.payload?.errors?.[0].message) {
|
||||
errorMessage = e.payload.errors[0].message;
|
||||
} else {
|
||||
errorMessage = 'Unknown Error occurred when attempting to resend';
|
||||
}
|
||||
|
||||
this.retryErrorMessage = htmlSafe(errorMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -58,22 +58,6 @@
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.emailErrorMessage}}
|
||||
<p class="error gh-box gh-box-error mt3 mb3">
|
||||
{{svg-jar "warning"}}
|
||||
|
||||
{{#if @publishOptions.willOnlyEmail}}
|
||||
Your post has been created but the email failed to send.
|
||||
{{else}}
|
||||
Your post has been published but the email failed to send.
|
||||
{{/if}}
|
||||
|
||||
Please verify your email settings if the error persists.
|
||||
<br><br>
|
||||
Email error: {{this.emailErrorMessage}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
<div class="gh-publish-cta">
|
||||
<GhTaskButton
|
||||
@task={{this.confirmTask}}
|
||||
|
@ -15,7 +15,6 @@ export default class PublishFlowOptions extends Component {
|
||||
@service settings;
|
||||
|
||||
@tracked errorMessage;
|
||||
@tracked emailErrorMessage;
|
||||
|
||||
// store any derived state from PublishOptions on creation so the copy
|
||||
// doesn't change whilst the post is saving
|
||||
@ -48,7 +47,6 @@ export default class PublishFlowOptions extends Component {
|
||||
@task({drop: true})
|
||||
*confirmTask() {
|
||||
this.errorMessage = null;
|
||||
this.emailErrorMessage = null;
|
||||
|
||||
try {
|
||||
yield this.args.saveTask.perform();
|
||||
@ -60,11 +58,6 @@ export default class PublishFlowOptions extends Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e?.name === 'EmailFailedError') {
|
||||
this.emailErrorMessage = e.message;
|
||||
return false;
|
||||
}
|
||||
|
||||
let errorMessage = '';
|
||||
|
||||
if (isServerUnreachableError(e)) {
|
||||
|
@ -12,8 +12,8 @@ import {task, taskGroup, timeout} from 'ember-concurrency';
|
||||
import {use} from 'ember-could-get-used-to-this';
|
||||
|
||||
const SHOW_SAVE_STATUS_DURATION = 3000;
|
||||
const CONFIRM_EMAIL_POLL_LENGTH = 1000;
|
||||
const CONFIRM_EMAIL_MAX_POLL_LENGTH = 15 * 1000;
|
||||
export const CONFIRM_EMAIL_POLL_LENGTH = 1000;
|
||||
export const CONFIRM_EMAIL_MAX_POLL_LENGTH = 15 * 1000;
|
||||
|
||||
// This component exists for the duration of the editor screen being open.
|
||||
// It's used to store the selected publish options, control the publishing flow
|
||||
|
Loading…
Reference in New Issue
Block a user