{"record":{"id":"4a30e4219e0f9b59","repo":"toeverything/AFFiNE","slug":"executionerror","errorCode":"ExecutionError","errorMessage":"Error occurred while executing ${evtName} handler of tool \"${tool?.toolName}\"","messagePattern":"Error occurred while executing (.+?) handler of tool \"(.+?)\"","errorType":"exception","errorClass":"BlockSuiteError","httpStatus":null,"severity":"error","filePath":"blocksuite/framework/std/src/gfx/tool/tool-controller.ts","lineNumber":287,"sourceCode":"      evt: PointerEventState,\n      tool?: BaseTool\n    ) => {\n      const evtHooks = hooks[evtName];\n      const stopHandler = evtHooks?.reduce((pre, hook) => {\n        return pre || hook(evt) === false;\n      }, false);\n\n      tool = tool ?? this.currentTool$.peek();\n\n      if (stopHandler) {\n        return false;\n      }\n\n      try {\n        tool?.[evtName](evt);\n        return true;\n      } catch (e) {\n        throw new BlockSuiteError(\n          ErrorCode.ExecutionError,\n          `Error occurred while executing ${evtName} handler of tool \"${tool?.toolName}\"`,\n          {\n            cause: e as Error,\n          }\n        );\n      }\n    };\n\n    /**\n     * Hook into the event lifecycle.\n     * All hooks will be executed despite the current active tool.\n     * This is useful for tools that need to perform some action before an event is handled.\n     * @param evtName\n     * @param handler\n     */\n    const addHook: ToolEventTarget['addHook'] = (evtName, handler) => {\n      hooks[evtName] = hooks[evtName] ?? [];","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/blocksuite/framework/std/src/gfx/tool/tool-controller.ts#L269-L305","documentation":"invokeToolHandler catches any exception thrown inside a gfx tool's event handler (e.g. pointer down/move) and rewraps it as a fatal ExecutionError naming the event and tool, preserving the original as cause so tool bugs are attributable.","triggerScenarios":"Thrown at blocksuite/framework/std/src/gfx/tool/tool-controller.ts:287 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the inner error (usually attached as cause or logged just before) for the real failure inside the tool handler.","Ensure the tool's handler for the event (pointerdown, drag, etc.) validates its inputs — null targets or missing models are the usual cause.","If a custom tool throws, wrap its handlers and rethrow with context so the failing tool name is preserved."],"exampleFix":"class MyTool extends BaseTool {\n  override pointerdown(e: PointerEventState) {\n    const target = this.gfx.getElementByPoint(e.point);\n    if (!target) return; // guard instead of throwing\n    // ...\n  }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}