Skip to content

Editor: show block errors instead of silently suppressing the save button - #2353

Merged
GermanBluefox merged 3 commits into
ioBroker:masterfrom
krobipd:harden-blockly-save-errors
Aug 24, 2026
Merged

Editor: show block errors instead of silently suppressing the save button#2353
GermanBluefox merged 3 commits into
ioBroker:masterfrom
krobipd:harden-blockly-save-errors

Conversation

@krobipd

@krobipd krobipd commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Builds on #2352 and contains its commits, because both change the same built editor files in admin/. Once #2352 is merged, this PR reduces to its own last commit — reviewing that commit alone is enough.

What users see

Every wave of "Blockly scripts cannot be saved anymore" reports (#487 in 2020, #1891 in the 9.0.x line, #2349 now) shares the same experience: the save button simply never appears, and nothing anywhere tells the user why. The reason is always some block throwing while the editor regenerates the script — but the only trace is a stack trace in the browser console, which most reporters never open ("Is it really so hard to press F12???" — that question from #1891 answers itself: for most users, yes).

Why it happens

The editor offers Save only after a change has been regenerated: workspaceToCode plus Xml.workspaceToDom (the workspace XML travels as a base64 comment behind the code). A block that throws inside that chain kills the change handler, and with it the save button — silently. #2352 fixes the two blocks that currently throw, but the next Blockly upgrade or block bug will hide exactly the same way again.

The change

  • The change handler catches the error and shows it in the editor's existing error dialog — once per distinct error, not again on every further change while the script stays broken. The console still gets the full stack trace.
  • A failing export (same serialization, triggered from the menu) shows its error too, instead of doing nothing at all.
  • The two new texts are translated in all 11 languages.

Saving stays blocked while a block is broken — that is correct, because the generated code would be broken too. The difference is that the user now sees which error stands between them and saving, and the next #2349 becomes a precise bug report instead of a wave of "cannot save" issues.

Verified

  • npm run lint, npm run test:package, npm run test:blockly, npm run build, npm test (declarations + integration, 280 passing) locally on Node 22
  • ✅ The rebuilt editor bundle contains the new dialog text; the error path reuses the existing DialogError mechanism (same as import errors)

🤖 Generated with Claude Code

…3, and functions without statements

Since 10.1.0, editing an existing Blockly script that contains a named timeout,
interval or schedule does not offer the Save button anymore — changes cannot be
saved, and edits made after touching such a block are lost (ioBroker#2349). Independently,
since at least 9.0.11 a script containing a function with a return value whose
"statements" checkbox is off cannot be saved either (ioBroker#1958).

The editor only decides "something changed — show Save" after it has regenerated
the script: `workspaceToCode` plus `Xml.workspaceToDom`. When any single block
throws inside that chain, the change handler dies and the Save button never
appears — without any visible error.

- The timer and schedule blocks answered `getVarModels()` with hand-built variable
  models in the Blockly 11 shape (`{ getId, name, type }`). Blockly 13 reads
  variable models through methods — `Xml.variablesToDom` calls `getName()`/
  `getType()` while saving — so every save of a script containing
  `timeouts_settimeout`, `timeouts_settimeout_variable`, `timeouts_setinterval`,
  `timeouts_setinterval_variable` or `schedule_create` threw
  `getName is not a function`. The pseudo models now carry
  `getName()`/`getType()`/`getId()`; the bare `name`/`type` properties stay for
  adapter block files written against the Blockly 11 shape (the compatibility
  promise of BLOCKLY_TS.md).
- The function generator read the STACK input unconditionally. With "statements"
  unchecked the mutation removes that input, and `statementToCode` throws for a
  missing one — the same trap the RETURN input is already guarded against one line
  below. The STACK read is now guarded the same way.

Why the snapshots stayed green: the harness only exercised code generation, and
that path touches `getId()` only. It now additionally saves every corpus block the
way the editor does it and reloads the saved XML to the same code — with the two
fixes reverted, this test fails on exactly the affected block types. A new fixture
covers the statement-less function, a state the toolbox (statements on by default)
can never show.

Verified on 10.1.1: `npm run test:blockly` 25 passing (24 + 1 failing with the fix
reverted), `npm run lint`, `npm run test:package` 72 passing, `npm run build`.
The snapshot diff against master is the new fixture's entry only — no existing
block's generated code changed.

Fixes ioBroker#2349
Fixes ioBroker#1958

🤖 Generated with [Claude Code](https://claude.com/claude-code)
… button

Every wave of "Blockly scripts cannot be saved anymore" reports (ioBroker#487 in 2020,
ioBroker#1891 in the 9.0.x line, ioBroker#2349 now) shares the same experience: the save button
simply never appears, and nothing tells the user why. The reason is always some
block throwing while the editor regenerates the script — but the only trace is a
stack trace in the browser console, which most reporters never open.

The editor offers Save only after a change has been regenerated: `workspaceToCode`
plus `Xml.workspaceToDom`. A block that throws inside that chain kills the change
handler, and with it the save button — silently. The preceding commit fixes the two
blocks that currently throw, but the next Blockly upgrade or block bug would hide
exactly the same way again.

- The change handler catches the error and shows it in the editor's existing error
  dialog — once per distinct error, not again on every further change while the
  script stays broken. The console still gets the full stack trace.
- A failing export (same serialization, triggered from the menu) shows its error
  too, instead of doing nothing at all.
- The two new texts are translated in all 11 languages.

Saving stays blocked while a block is broken — that is correct, because the
generated code would be broken too. The difference is that the user now sees which
error stands between them and saving, and the next ioBroker#2349 becomes a precise bug
report instead of a wave of "cannot save" issues.

Verified on 10.1.1: `npm run lint`, `npm run test:blockly` 25 passing,
`npm run test:package` 72 passing, `npm run build`. The rebuilt bundle carries the
new dialog texts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@krobipd
krobipd force-pushed the harden-blockly-save-errors branch from d796412 to 63b796e Compare August 24, 2026 19:54
@GermanBluefox
GermanBluefox enabled auto-merge (squash) August 24, 2026 20:30
@GermanBluefox
GermanBluefox merged commit a23aba2 into ioBroker:master Aug 24, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants