diff --git a/.serena/memories/critical-info.md b/.serena/memories/critical-info.md index 42d6861913..acb3f560fe 100644 --- a/.serena/memories/critical-info.md +++ b/.serena/memories/critical-info.md @@ -1,14 +1,21 @@ -You are working on the GitHub project penpot/penpot. - -# Working with Penpot Designs - -Before working with Penpot designs, call the `high_level_overview` tool of the Penpot MCP server. -It explains the JavaScript API, which you can use to automate tasks via the `execute_code` tool. - -# Critical Memories - -* Before creating a commit, read `creating-commits`. -* When working on the Penpot frontend ... - - read the file `frontend/AGENTS.md` for an overview - - to understand the connection between the JavaScript API and the ClojureScript code, read memory `frontend/js-api-to-cljs-binding`. - - to understand how to execute ClojureScript code in the Penpot frontend, read memory `frontend/cljs-repl`. +You are working on the GitHub project penpot/penpot. + +# Working with Penpot Designs + +Before working with Penpot designs, call the `high_level_overview` tool of the Penpot MCP server. +It explains the JavaScript API, which you can use to automate tasks via the `execute_code` tool. + +# Critical Memories + +* Before creating a commit, read `creating-commits`. +* When working on the Penpot frontend ... + - read the file `frontend/AGENTS.md` for an overview + - to understand the connection between the JavaScript API and the ClojureScript code, read memory `frontend/js-api-to-cljs-binding`. + - to understand how to execute ClojureScript code in the Penpot frontend, read memory `frontend/cljs-repl`. + +# Detecting Frontend Crashes + +The Penpot frontend can crash silently from the JS API's perspective: `execute_code` calls return successfully, but 1-2s later the workspace becomes unusable (Internal Error page). +The `execute_code` tool then stops working, but `cljs_repl` still works. Use it to detect a crash via `(some? (:exception @app.main.store/state))`. +For details on handling crashes, read memory `frontend/handling-crashes`. + diff --git a/.serena/memories/frontend/handling-crashes.md b/.serena/memories/frontend/handling-crashes.md new file mode 100644 index 0000000000..1c6b0ac207 --- /dev/null +++ b/.serena/memories/frontend/handling-crashes.md @@ -0,0 +1,41 @@ +# Handling Penpot Frontend Crashes + +When the Penpot frontend crashes, it usually shows the **Internal Error** page (title text "Something bad happened", class `main_ui_static__download-link`). + +A typical error pattern is: Changes go through (JS API, `execute_code`), but about 1-2s later, an `update-file` request hits the backend with the change and gets rejected. +So be sure to check the status for a crash. + +After a crash, `execute_code` is unusable (no instances connected), and any data in `storage` is lost, but `cljs_repl` keeps working! + +## 1. Detect the crash + +cljs REPL `(some? (:exception @app.main.store/state))` returns `true` when the Internal Error page is showing, +`false` on a healthy workspace (and after a successful reload). + +## 2. Read the cause + +The exception is stored at `(:exception @app.main.store/state)`. Useful keys: + +- `:type`, `:code`, `:status` — error class (e.g. `:validation` / `:referential-integrity` / `400`) +- `:hint`, `:details` — human-readable explanation; `:details` typically contains a vector of validation problems with `:shape-id`, `:page-id`, `:args`, etc. +- `:uri` — the API endpoint that returned the error (e.g. `update-file`) +- `:app.main.errors/instance` — the underlying JS Error object +- `:app.main.errors/trace` — JS stack trace string (only shows the response-handling path, not the dispatch site that produced the bad change) + +``` +(let [ex (:exception @app.main.store/state)] + (select-keys ex [:type :code :status :hint :details :uri])) +``` + +For backend validation errors (`:type :validation`), `:details` is the most informative field — it tells you exactly which shape and which invariant was violated. + +## 3. Recover and continue testing + +Reload steps: +1. List tabs with `playwright:browser_tabs` (`action: list`) and find the Penpot workspace tab (URL contains `/#/workspace`, title ends in `- Penpot`). +2. If it isn't the current tab, select it via `playwright:browser_tabs` (`action: select`, `index: `). The selected tab's URL then appears as "Page URL" in the result. +3. Reload by calling `playwright:browser_navigate` with that same URL. +4. Confirm recovery: `(some? (:exception @app.main.store/state))` should now return `false`. + +Whether the offending change persists depends on the crash type: +For **backend-rejected changes** (e.g. `:type :validation`, 4xx on `update-file`), changes are NOT persisted. Reload restores the pre-crash state — safe to retry.