mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 08:15:41 +00:00
fix: show the translated check-your-Sent message for an unconfirmed send #1019
A send answered without an EmailSubmission threw a fixed English message, which the composer showed as is in every language. It now throws `SendUnconfirmedError`, and the composer shows the existing `send_timeout` text, the same advice as for a send whose answer was lost: check Sent before sending again.
This commit is contained in:
@@ -46,7 +46,7 @@ import { appendPlainTextSignature, getPlainTextSignature, plainTextBodyHasSignat
|
||||
import { findComposeIdentityId, findDraftIdentityId, findReplyIdentityId, resolveReplyFrom } from "@/lib/reply-identity";
|
||||
import { buildReplyRecipients, isSelfSent } from "@/lib/reply-recipients";
|
||||
import { computeReplyThreadingHeaders, type ReplyThreadingHeaders } from "@/lib/email-threading";
|
||||
import { RecipientsRejectedError, RequestTimeoutError, ScheduleTooLateError, formatRejectedRecipients } from "@/lib/jmap/client";
|
||||
import { RecipientsRejectedError, RequestTimeoutError, ScheduleTooLateError, SendUnconfirmedError, formatRejectedRecipients } from "@/lib/jmap/client";
|
||||
import {
|
||||
rewriteCidImagesForEditor,
|
||||
replaceInlineImagePlaceholders,
|
||||
@@ -2607,8 +2607,9 @@ export function EmailComposer({
|
||||
// A timeout is not a clean failure: the submission may have reached the
|
||||
// server and gone out, with only the answer lost. Saying "send failed"
|
||||
// would invite a re-send and a duplicate, so point at Sent instead (#702).
|
||||
// The same goes for a send the server answered without confirming it.
|
||||
toast.error(
|
||||
err instanceof RequestTimeoutError
|
||||
err instanceof RequestTimeoutError || err instanceof SendUnconfirmedError
|
||||
? t('send_timeout')
|
||||
: err instanceof ScheduleTooLateError
|
||||
? t('schedule_send_too_late')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { JMAPClient } from '../jmap/client';
|
||||
import { JMAPClient, SendUnconfirmedError } from '../jmap/client';
|
||||
|
||||
/**
|
||||
* #849: replacing a draft (autosave, send) used to bundle the destroy of the
|
||||
@@ -238,7 +238,10 @@ describe('compose failure recovery', () => {
|
||||
beforeEach(() => { vi.restoreAllMocks(); vi.spyOn(console, 'error').mockImplementation(() => {}); });
|
||||
it.each([{ methodError: true }, { missingSubmission: true }])('does not claim success or delete the old draft without confirmation: %j', async options => {
|
||||
const client = createClient(); const captured = mockFlow(options);
|
||||
await expect(client.sendEmail(['bob@example.com'], 'Subject', 'body', undefined, undefined, 'identity-1', 'user@example.com', 'old-draft')).rejects.toThrow();
|
||||
await expect(client.sendEmail(['bob@example.com'], 'Subject', 'body', undefined, undefined, 'identity-1', 'user@example.com', 'old-draft')).rejects.toThrow(
|
||||
// Only the missing submission is unconfirmed; a method error is a plain failure.
|
||||
options.missingSubmission ? SendUnconfirmedError : Error,
|
||||
);
|
||||
expect(emailSetCalls(captured).some(call => call.destroy)).toBe(false);
|
||||
});
|
||||
it('accepts empty notCreated maps as success', async () => {
|
||||
|
||||
+12
-1
@@ -775,6 +775,17 @@ export class RecipientsRejectedError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The send request came back without an EmailSubmission: nothing confirms the
|
||||
* message left, and it may still have. The draft is kept.
|
||||
*/
|
||||
export class SendUnconfirmedError extends Error {
|
||||
constructor() {
|
||||
super('Send confirmation was not received. Check Sent before sending again. Your draft has been kept.');
|
||||
this.name = 'SendUnconfirmedError';
|
||||
}
|
||||
}
|
||||
|
||||
/** "report.pdf" -> "report (2).pdf", the way Stalwart's onExists "rename" names copies. */
|
||||
function numberedFileName(name: string, n: number): string {
|
||||
const dot = name.lastIndexOf('.');
|
||||
@@ -4193,7 +4204,7 @@ export class JMAPClient implements IJMAPClient {
|
||||
// all. Nothing confirms the message left: report a failure and keep the
|
||||
// old draft rather than replacing it as if the send had worked.
|
||||
if (!emailSubmissionId) {
|
||||
throw new Error('Send confirmation was not received. Check Sent before sending again. Your draft has been kept.');
|
||||
throw new SendUnconfirmedError();
|
||||
}
|
||||
|
||||
// With every recipient refused nothing was queued, yet the submission
|
||||
|
||||
Reference in New Issue
Block a user