mirror of
https://github.com/karatektus/pl_mail.git
synced 2026-10-25 01:54:10 +00:00
A send is held for ten seconds so it can be called off. The browser marked the end of the CANCEL window — eight seconds — by asking the server to tidy up, and that answer carried "Message sent." So the confirmation preceded the attempt by two seconds, every time, for everybody. And nothing ever corrected it. All three senders turn a failure into a bare `false`, which SendMessageHandler treated as handled: no retry, no failed-transport row, nothing. SmtpMailSender goes further and binds the transport exception without using it, so a hard SMTP rejection left zero trace anywhere in the system. The user was told the mail had gone, and it had not. Now the eight-second mark only tidies, and the outcome is published from the worker when there is one — success or failure, over the live-updates stream that is already there. The failure toast is the case that had no surface at all. It publishes RENDERED html, because the alternative is a toast built in JavaScript, which is a second copy of _toast.html.twig drifting from the first. Best effort, and honestly so: with the hub down there is no toast, which is a confirmation missing rather than a confirmation that lies. WHAT THE E2E SUITE CAN AND CANNOT SHOW It cannot show the toast. The test app runs MESSENGER_TRANSPORT_DSN=in-memory://, so a send dispatched by a browser request is discarded when the request ends and no worker can pick it up — which also means those specs were only ever asserting the premature claim. They now pin the half that was wrong: that nothing announces an outcome it does not have. The publishing side is covered by SendOutcomeNotifierTest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
47 lines
2.3 KiB
Twig
47 lines
2.3 KiB
Twig
{#
|
|
compose/_undo_too_late.html.twig
|
|
─────────────────────────────────────────────────────────────────────────────
|
|
The cancel arrived after SendMessageHandler had already claimed the message.
|
|
|
|
This template exists because the alternative was lying. Every undo used to
|
|
answer with the dock-undo stream — "send cancelled", window restored — whether
|
|
or not the cancel had actually taken, and a cancel clicked in the last fraction
|
|
of the hold does not take. The user was told the one thing that was not true
|
|
about the one action that cannot be reversed.
|
|
|
|
So: an ERROR toast, not an info one, because something the user asked for did
|
|
not happen; and no window, because there is no draft to reopen. Restoring the
|
|
composer here would put an editable copy of an already-sent mail on screen, and
|
|
the next autosave would file it as a draft standing beside the sent copy.
|
|
|
|
And the page is left exactly as a send that ran its course leaves it, by
|
|
including the very same partial: whatever window this cancel came from is
|
|
describing a message that has gone, so it closes, and the message takes its
|
|
place in the conversation. That used to be a bare "empty the dock", which was
|
|
right only because the inline composer had already been replaced by a
|
|
countdown bar before this could be reached. It is not any more — the window is
|
|
still open, still holding a copy of a mail that is on the wire — so saying
|
|
"too late" without also closing it would leave the user an editable draft of
|
|
something already sent.
|
|
|
|
Variables: message, thread (MessageThread|null), ctx
|
|
#}
|
|
<turbo-stream action="append" target="toast-region">
|
|
<template>
|
|
{% include '_partials/_toast.html.twig' with {
|
|
type: 'error',
|
|
message: 'toast.send_too_late'|trans,
|
|
extra: { hide_after: 8000 },
|
|
} only %}
|
|
</template>
|
|
</turbo-stream>
|
|
|
|
{# The error above IS this send's notification. Nothing has to be suppressed
|
|
any more: _sent.stream stopped claiming success, because at the moment it
|
|
runs nobody knows whether the send worked. #}
|
|
{% include 'compose/_sent.stream.html.twig' with {
|
|
message: message,
|
|
thread: thread,
|
|
ctx: ctx,
|
|
} only %}
|