Skip to content

Commit

Permalink
#8063: improve user-visible error message for InsertAtCursorEffect br…
Browse files Browse the repository at this point in the history
…ick (#8069)
  • Loading branch information
twschiller committed Mar 26, 2024
1 parent 17c212b commit 13f40b9
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
17 changes: 17 additions & 0 deletions src/bricks/effects/InsertAtCursorEffect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
*/

import InsertAtCursorEffect from "@/bricks/effects/InsertAtCursorEffect";
import { unsafeAssumeValidArg } from "@/runtime/runtimeTypes";
import { brickOptionsFactory } from "@/testUtils/factories/runtimeFactories";
import { BusinessError } from "@/errors/businessErrors";

const brick = new InsertAtCursorEffect();

Expand All @@ -27,4 +30,18 @@ describe("InsertAtCursorEffect", () => {
it("is root-aware", async () => {
await expect(brick.isRootAware()).resolves.toBe(false);
});

it("throws business error if insert fails", async () => {
// `jsdom` doesn't implement execCommand
document.execCommand = jest.fn().mockReturnValue(false);

await expect(
brick.run(
unsafeAssumeValidArg({
text: "test",
}),
brickOptionsFactory(),
),
).rejects.toThrow(BusinessError);
});
});
19 changes: 17 additions & 2 deletions src/bricks/effects/InsertAtCursorEffect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ import { type Schema } from "@/types/schemaTypes";
import { isEmpty } from "lodash";
import selectionController from "@/utils/selectionController";
import type { PlatformCapability } from "@/platform/capabilities";
import { insertAtCursorWithCustomEditorSupport } from "@/contentScript/textEditorDom";
import {
ExecCommandError,
insertAtCursorWithCustomEditorSupport,
} from "@/contentScript/textEditorDom";
import { propertiesToSchema } from "@/utils/schemaUtils";
import { expectContext } from "@/utils/expectContext";
import { BusinessError } from "@/errors/businessErrors";

/**
* Insert text at the cursor position. For use with text snippets, etc.
Expand Down Expand Up @@ -75,7 +79,18 @@ class InsertAtCursorEffect extends EffectABC {
// https://github.com/pixiebrix/pixiebrix-extension/pull/7827#issuecomment-1979884573
selectionController.restoreWithoutClearing();

await insertAtCursorWithCustomEditorSupport(text);
try {
await insertAtCursorWithCustomEditorSupport(text);
} catch (error) {
if (error instanceof ExecCommandError) {
throw new BusinessError(
"Error inserting text at cursor. Ensure there is a focused editor in the target frame",
{ cause: error },
);
}

throw error;
}
}
}

Expand Down
22 changes: 21 additions & 1 deletion src/contentScript/textEditorDom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ import { expectContext } from "@/utils/expectContext";
import { dispatchPasteForDraftJs } from "@/utils/domFieldUtils";
import focusController from "@/utils/focusController";

/**
* Error to be thrown when document.execCommand fails.
*
* Treated as application error, callers should convert into a BusinessError subclass where appropriate.
*
* @see document.execCommand
*/
export class ExecCommandError extends Error {
override name = "ExecCommandError";
readonly commandId: string;

constructor(message: string, { commandId }: { commandId: string }) {
super(message);
this.commandId = commandId;
}
}

/**
* @file Text Editor DOM utilities that might call the pageScript.
*
Expand All @@ -39,6 +56,7 @@ import focusController from "@/utils/focusController";
* - Plain content editable (Gmail, etc.)
* - CKEditor 4/5
*
* @throws {ExecCommandError} if the text could not be inserted with InsertTextError
*/
export async function insertAtCursorWithCustomEditorSupport(text: string) {
expectContext(
Expand Down Expand Up @@ -69,6 +87,8 @@ export async function insertAtCursorWithCustomEditorSupport(text: string) {
focusController.restoreWithoutClearing();

if (!document.execCommand("insertText", false, text)) {
throw new Error("Failed to insert text using execCommand");
throw new ExecCommandError("Failed to insert text using execCommand", {
commandId: "insertText",
});
}
}
1 change: 0 additions & 1 deletion src/tsconfig.strictNullChecks.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
"./bricks/available.ts",
"./bricks/effects/AddDynamicTextSnippet.ts",
"./bricks/effects/AddTextSnippets.ts",
"./bricks/effects/InsertAtCursorEffect.test.ts",
"./bricks/effects/InsertAtCursorEffect.ts",
"./bricks/effects/ToggleQuickbarEffect.ts",
"./bricks/effects/alert.ts",
Expand Down

0 comments on commit 13f40b9

Please sign in to comment.