From 0e3634d2d26d98d11d9d45f98eb29281b07b78de Mon Sep 17 00:00:00 2001 From: Mike Amirault Date: Thu, 11 Jun 2026 09:53:08 -0400 Subject: [PATCH] [PM-38357] Surface more descriptive error messages from server on Send edit failure (#21067) * [PM-38357] Surface more descriptive error messages from server on Send edit failure * Address AI review comments * Re-add guard and adjust abstract method documentation --- apps/browser/src/_locales/en/messages.json | 4 ---- apps/desktop/src/locales/en/messages.json | 4 ---- apps/web/src/locales/en/messages.json | 4 ---- .../abstractions/send-form.service.ts | 4 ++-- .../components/send-form.component.ts | 2 +- .../services/default-send-form.service.ts | 24 +++++++++---------- 6 files changed, 14 insertions(+), 28 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index e0d8b9529d6..f78d60bc970 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -6667,10 +6667,6 @@ "message": "Progress bar", "description": "This is the name of a page component that displays progress to the user. This string will be used to label the progress bar for a screenreader when multiple progress bars are on a page, like 'Progress bar 1' and 'Progress bar 2'." }, - "saveSendEditsFailed": { - "message": "Saving Send edits failed", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "hideEmailPolicyInEffect": { "message": "Your organization requires email visibility. Uncheck \"Hide your email from viewers\" to save." }, diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 305db5f0873..4bb600e922d 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -5259,10 +5259,6 @@ "message": "Send has unsaved edits. Are you sure you want to leave?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "saveSendEditsFailed": { - "message": "Saving Send edits failed", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "viewTextSendHeader": { "message": "View text" }, diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 5bda20989b5..9f94637d126 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -14233,10 +14233,6 @@ "message": "Send has unsaved edits. Are you sure you want to leave?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "saveSendEditsFailed": { - "message": "Saving Send edits failed", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "hideMyEmail": { "message": "Hide my email address from recipients." }, diff --git a/libs/tools/send/send-ui/src/send-form/abstractions/send-form.service.ts b/libs/tools/send/send-ui/src/send-form/abstractions/send-form.service.ts index bb4f069a765..f4b9d9508e6 100644 --- a/libs/tools/send/send-ui/src/send-form/abstractions/send-form.service.ts +++ b/libs/tools/send/send-ui/src/send-form/abstractions/send-form.service.ts @@ -58,8 +58,8 @@ export abstract class SendFormService { abstract initializeSendForm(sendFormConfig: SendFormConfig): Promise; /** - * Submits the Send form. Returns `undefined` if the form has an - * error or the service encounters a network error on submission + * Submits the Send form. This will return `undefined` if the Send form had errors preventing + * its submission, and throw any errors it receives from encryption, decryption, or the API call */ abstract submitSendForm(): Promise; diff --git a/libs/tools/send/send-ui/src/send-form/components/send-form.component.ts b/libs/tools/send/send-ui/src/send-form/components/send-form.component.ts index bcf7bcf7d47..eed5c4fb033 100644 --- a/libs/tools/send/send-ui/src/send-form/components/send-form.component.ts +++ b/libs/tools/send/send-ui/src/send-form/components/send-form.component.ts @@ -135,7 +135,7 @@ export class SendFormComponent implements AfterViewInit { submit = async () => { const sendView = await this.sendFormService.submitSendForm(); - // Send form had errors or otherwise failed to submit + // Send form had errors if (!sendView) { return; } diff --git a/libs/tools/send/send-ui/src/send-form/services/default-send-form.service.ts b/libs/tools/send/send-ui/src/send-form/services/default-send-form.service.ts index eb2fc0e32e1..1fcd838d4d4 100644 --- a/libs/tools/send/send-ui/src/send-form/services/default-send-form.service.ts +++ b/libs/tools/send/send-ui/src/send-form/services/default-send-form.service.ts @@ -13,7 +13,6 @@ import { SendView } from "@bitwarden/common/tools/send/models/view/send.view"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; -import { LogService } from "@bitwarden/logging"; import { SendItemDialogResult } from "../../add-edit/send-add-edit-dialog.component"; import { SendPolicyService } from "../../services/send-policy.service"; @@ -29,7 +28,6 @@ import { SendForm } from "../send-form-container"; export class DefaultSendFormService implements SendFormService { private dialogService = inject(DialogService); private toastService = inject(ToastService); - private logService = inject(LogService); private formBuilder = inject(FormBuilder); private accountService = inject(AccountService); private sendApiService = inject(SendApiService); @@ -112,6 +110,7 @@ export class DefaultSendFormService implements SendFormService { } } + let sendView: SendView; try { const sendData = await this.sendService.encrypt( this.updatedSendView, @@ -120,20 +119,19 @@ export class DefaultSendFormService implements SendFormService { null, ); const newSend = await this.sendApiService.save(sendData); - const sendView = await this.decryptSend(newSend); - this._originalSendView.set(null); - this.updatedSendView = null; - this._submitting.set(false); - return sendView; + sendView = await this.decryptSend(newSend); } catch (err) { - this.logService.error(err); - this.toastService.showToast({ - message: this.i18nService.t("saveSendEditsFailed"), - variant: "error", - }); + // We surface any errors but make sure that the submitting + // status signal is set to false before we do this._submitting.set(false); - return; + throw err; } + + this._originalSendView.set(null); + this.updatedSendView = null; + this._submitting.set(false); + + return sendView; } sendFormHasEdits() {