Skip to content

Fix/screen error reporting - #3816

Open
jmthomas wants to merge 3 commits into
mainfrom
fix/screen-error-reporting
Open

Fix/screen error reporting#3816
jmthomas wants to merge 3 commits into
mainfrom
fix/screen-error-reporting

Conversation

@jmthomas

@jmthomas jmthomas commented Sep 2, 2026

Copy link
Copy Markdown
Member

What changed

Consolidated the error reporting in the TlmViewer widget chain. Some widgets now emit errors that are rescued at the screen level. LINEGRAPH now confirms that all the items exist instead of just not graphing. TITLE now enforces a single parameter which will error a screen and require a user fix but has been the case since COSMOS 5.0. Extraneous END statements now error a screen and require a user fix but this helps expose weird rendering errors.

Why it changed

Customer reported At undefined: (undefined) TypeError: Cannot read properties of undefined (reading 'push'). I think this was due to the Graph widget having an invalid item.

Testing strategy

Went through all screens and looked for render errors and console log errors. All resolved successfully.

jmthomas and others added 3 commits September 2, 2026 15:54
Widgets reported errors four different ways, and ArrayplotWidget pushed
to a `this.errors` array that never existed, so a lost stream connection
died with a TypeError instead of a message. Give Widget.js one pair of
helpers - screenError() to throw for definition errors, emitScreenError()
to emit for errors after the widget is built (errorCaptured can't see
async throws) - and route every widget and Openc3Screen site through a
single addError().

Also fixes errors that were reported but never seen: rerender() cleared
the list after the new widgets had filled it, parseDefinition() threw
outside any errorCaptured context, and graph items were never checked for
existence because they don't emit addItem. Re-parsing now resets
actualScreenItems so a screen with no polled items stops polling the
previous definition's.

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

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Widgets reported errors four different ways, and ArrayplotWidget pushed
to a `this.errors` array that never existed, so a lost stream connection
died with a TypeError instead of a message. Give Widget.js one pair of
helpers - screenError() to throw for definition errors, emitScreenError()
to emit for errors after the widget is built (errorCaptured can't see
async throws) - and route every widget and Openc3Screen site through a
single addError().

Also fixes errors that were reported but never seen: rerender() cleared
the list after the new widgets had filled it, parseDefinition() threw
outside any errorCaptured context, and graph items were never checked for
existence because they don't emit addItem. Re-parsing now resets
actualScreenItems so a screen with no polled items stops polling the
previous definition's.

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

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jmthomas
jmthomas requested review from EmilyRagan and ryan-pratt and a lite review from Copilot September 2, 2026 23:47
@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 31.25000% with 44 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.19%. Comparing base (d181feb) to head (5ea93a9).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
.../openc3-vue-common/src/components/Openc3Screen.vue 30.76% 23 Missing and 4 partials ⚠️
...s/packages/openc3-vue-common/src/widgets/Widget.js 25.00% 6 Missing ⚠️
...ackages/openc3-vue-common/src/components/Graph.vue 0.00% 4 Missing ⚠️
.../openc3-vue-common/src/widgets/ArrayplotWidget.vue 0.00% 2 Missing and 1 partial ⚠️
...nc3-vue-common/src/components/EditScreenDialog.vue 66.66% 1 Missing ⚠️
...es/openc3-vue-common/src/widgets/DynamicWidget.vue 0.00% 1 Missing ⚠️
.../openc3-vue-common/src/widgets/LimitsbarWidget.vue 0.00% 1 Missing ⚠️
...enc3-vue-common/src/widgets/LimitscolumnWidget.vue 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3816      +/-   ##
==========================================
- Coverage   79.19%   79.19%   -0.01%     
==========================================
  Files         894      894              
  Lines       67034    67077      +43     
  Branches     2553     2566      +13     
==========================================
+ Hits        53087    53120      +33     
- Misses      13284    13297      +13     
+ Partials      663      660       -3     
Flag Coverage Δ
frontend 65.97% <31.25%> (-0.06%) ⬇️
python 79.38% <ø> (+0.05%) ⬆️
ruby-api 82.22% <ø> (-0.05%) ⬇️
ruby-backend 84.51% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

sonarqubecloud Bot commented Sep 2, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are a couple of confirmed edge-case bugs in the updated Openc3Screen error/reporting and tlm-availability in-flight handling that can reintroduce “(undefined)” error formatting and apply stale responses when item sets change but lengths match.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR consolidates and hardens TlmViewer screen/widget error reporting so definition-time errors are attributed to the correct screen-definition line, and runtime/async errors (e.g., streaming disconnects) reliably surface at the screen level instead of being lost or causing unrelated failures.

Changes:

  • Centralized screen-definition error creation (screenError) and async/runtime error propagation (emitScreenError) via new widget helpers and screen-level addError.
  • Added explicit item-existence checks for streaming graph widgets (so typos become visible screen errors instead of silent empty series).
  • Tightened screen parsing robustness (extra END now reports a targeted definition error; screen re-parse resets polling state to avoid stale item polling).
File summaries
File Description
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/widgets/Widget.js Adds screenError, emitScreenError, and checkScreenItems; uses screenError in param verification.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/widgets/TitleWidget.vue Enforces TITLE <Text> with verifyNumParams (breaking-change behavior now explicit).
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/widgets/LinegraphWidget.vue Bubbles embedded Graph errors to the screen via emitScreenError.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/widgets/LimitscolumnWidget.vue Switches ad-hoc thrown object to structured screenError.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/widgets/LimitsbarWidget.vue Switches ad-hoc thrown object to structured screenError.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/widgets/GraphWidget.js Avoids seeding undefined items; requests screen-level existence validation for graph items.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/widgets/DynamicWidget.vue Reports unknown widget load failures as structured screenError for proper attribution.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/widgets/ArrayplotWidget.vue Replaces direct error-list mutation with screen-bubbled emitScreenError; guards __time axis generation when no series exist.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/components/Openc3Screen.vue Centralizes error ingestion (addError), catches parse-time throws, prevents extra END stack underflow, and adds item-existence checks for streaming graphs.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/components/Graph.vue Adds explicit error emit and forwards internal errors upward for embedded screen display.
openc3-cosmos-init/plugins/packages/openc3-vue-common/src/components/EditScreenDialog.vue Dedupes displayed errors and avoids prepending location info when no definition line exists.
openc3-cosmos-init/plugins/packages/openc3-js-common/src/services/cable.js Suppresses disconnected callbacks caused by explicit unsubscribe/unmount from being treated as connection problems.
openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/screens/other.txt Updates demo screen TITLE usage to single-parameter form.
openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/screens/adcs.txt Updates demo screen TITLE usage to single-parameter form.
openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST/screens/other.txt Updates demo screen TITLE usage to single-parameter form.
openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST/screens/adcs.txt Updates demo screen TITLE usage to single-parameter form.
Review details

Suppressed comments (1)

openc3-cosmos-init/plugins/packages/openc3-vue-common/src/components/Openc3Screen.vue:1192

  • In the get_tlm_available catch path, the fallback reset of actualScreenItems is guarded only by requestedItems.length === this.screenItems.length. If a re-parse swaps items but preserves length, this can restore polling for the wrong set/order of items.
          .catch((error) => {
            console.error('Error getting tlm available', error)
            if (requestedItems.length === this.screenItems.length) {
              this.actualScreenItems = [...this.screenItems]
            }
  • Files reviewed: 16/16 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +610 to +621
let names = []
let lines = []
for (const widget of this.dynamicWidgets) {
names.push(widget.name)
lines.push(widget.lineNumber)
}
// Warn about any of the Dynamic widgets we found .. they could be typos
this.addError({
type: 'usage',
message: `Unknown widget! Are these widgets: ${names.join(',')}?`,
lineNumber: lines.join(','),
})
Comment on lines +1141 to +1149
// The screen can be re-parsed while this is in flight, which leaves the
// response describing items we no longer have
const requestedItems = [...this.screenItems]
this.api
.get_tlm_available(this.screenItems, {}, { 'Ignore-Errors': '403' })
.get_tlm_available(requestedItems, {}, { 'Ignore-Errors': '403' })
.then((data) => {
if (requestedItems.length !== this.screenItems.length) {
return
}
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