Skip to content

Print error code texts - #564

Open
urfeex wants to merge 20 commits into
UniversalRobots:masterfrom
urfeex:error_codes
Open

Print error code texts#564
urfeex wants to merge 20 commits into
UniversalRobots:masterfrom
urfeex:error_codes

Conversation

@urfeex

@urfeex urfeex commented Sep 4, 2026

Copy link
Copy Markdown
Member

Add string replacement of logged error codes

Instead of logging a plain "C100A3" we can log "C100A3: Robot mode changed to: POWER_OFF"

It generates a C++ header from the online json documentation for error codes.
Local overwrites can be specified for each error_code/argument combination
either as json or in a C++ file. Currently, that contains replacing the
robot mode argument in C100 with the robot mode string.

This PR implements:

  • A Python script to generate a C++ header representing the error code texts
  • An updated ErrorCodeMessage::toString() method that
    • prints "C<err_code>A<err_arg>: " if the error code is known. is one of (in order)
      • The one manually defined in error_code_overrides.cpp
      • The one from the json matching code and arg
      • The one from the json matching the code, if full code/arg combination can't be found
    • prints "C<err_code>A<err_arg>" only, if no entry can be found
  • A json override file to override individual texts. E.g. if we would like to give additional information on certain error codes inside URCL
  • Two custom CMake targets
    • generate_error_codes re-generates the header based on the online json
    • check_error_codes checks whether the generated header was generated on the version noted by the online json
  • Unit tests covering the ErrorCodeMessage::toString() method
  • A nightly GitHub workflow that checks whether the generated header matches the version in the online JSON. If not, a PR is automatically created updating the header.

Note

Medium Risk
User-visible log and callback strings change for all error-code messages, and a large generated header must stay in sync with upstream JSON; risk is operational rather than security-critical.

Overview
Error code messages now include UR documentation text instead of only C<code>A<arg>. ErrorCodeMessage::toString() appends a description from a runtime override, an exact (code, arg) lookup, or a code-only fallback in the generated map.

A codegen and sync pipeline adds scripts/generate_error_codes.py, commits auto-generated error_code_texts.h (UR ErrorCodes JSON v40.121.0), and supports static tweaks via scripts/error_code_overrides.json plus dynamic cases in src/ur/error_code_overrides.cpp (e.g. C100 → robot mode name). CMake exposes generate_error_codes / check_error_codes targets when Python is available.

Automation and tests: a nightly GitHub workflow compares the committed header version to upstream JSON and can open a labeled PR to regenerate it; codecov ignores the generator script. Unit tests cover the lookup chain and overrides. Primary-interface logging now prints toString() with %s format (no extra prefix wrapper).

Reviewed by Cursor Bugbot for commit 37841f3. Bugbot is set up for automated code reviews on this repo. Configure here.

Instead of logging C100A3 we can log "Robot mode changed to: POWER_OFF"

It generates a C++ header from the online json documentation for error codes.
Local overwrites can be specified for each error_code/argument combination
either as json or in a C++ file. Currently, that contains replacing the
robot mode argument in C100 with the robot mode string.

This adds two custom CMake target

- generate_error_codes re-generates the header based on the online json
- check_error_codes checks whether the generated header was generated on the version noted by the online json
@urfeex urfeex added the enhancement New feature or request label Sep 4, 2026
@urfeex
urfeex requested a balanced review from Copilot September 4, 2026 05:17
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.97%. Comparing base (f4f8870) to head (37841f3).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
src/ur/error_code_overrides.cpp 81.81% 2 Missing ⚠️
src/primary/robot_message/error_code_message.cpp 90.90% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #564      +/-   ##
==========================================
- Coverage   81.19%   80.97%   -0.23%     
==========================================
  Files         117      119       +2     
  Lines        7146     7173      +27     
  Branches     3201     3215      +14     
==========================================
+ Hits         5802     5808       +6     
- Misses        961      975      +14     
- Partials      383      390       +7     
Flag Coverage Δ
check_version_ur10-3.15.8 12.82% <62.96%> (+0.17%) ⬆️
check_version_ur10e-10.11.0 11.18% <0.00%> (-0.05%) ⬇️
check_version_ur10e-5.15.2 11.18% <0.00%> (-0.24%) ⬇️
check_version_ur12e-10.12.1 11.18% <0.00%> (-0.09%) ⬇️
check_version_ur12e-5.25.1 11.18% <0.00%> (-0.28%) ⬇️
check_version_ur15-10.12.1 11.18% <0.00%> (-0.09%) ⬇️
check_version_ur15-5.25.1 11.23% <0.00%> (-0.20%) ⬇️
check_version_ur16e-10.12.1 11.18% <0.00%> (-0.05%) ⬇️
check_version_ur16e-5.25.1 11.18% <0.00%> (-0.79%) ⬇️
check_version_ur18-10.12.1 11.18% <0.00%> (-0.05%) ⬇️
check_version_ur18-5.25.1 11.18% <0.00%> (-0.24%) ⬇️
check_version_ur20-10.12.1 11.18% <0.00%> (-0.09%) ⬇️
check_version_ur20-5.25.1 11.18% <0.00%> (-0.36%) ⬇️
check_version_ur3-3.14.3 11.91% <29.62%> (+0.36%) ⬆️
check_version_ur30-10.12.1 11.18% <0.00%> (-0.09%) ⬇️
check_version_ur30-5.25.1 11.18% <0.00%> (-0.24%) ⬇️
check_version_ur3e-10.11.0 11.18% <0.00%> (-0.09%) ⬇️
check_version_ur3e-5.9.4 11.23% <0.00%> (-0.24%) ⬇️
check_version_ur5-3.15.8 11.37% <0.00%> (-0.08%) ⬇️
check_version_ur5e-10.11.0 11.18% <0.00%> (-0.09%) ⬇️
check_version_ur5e-5.12.8 11.23% <0.00%> (-0.05%) ⬇️
check_version_ur7e-10.11.0 11.18% <0.00%> (-0.14%) ⬇️
check_version_ur7e-5.22.2 11.18% <0.00%> (-0.28%) ⬇️
check_version_ur8long-10.12.1 11.18% <0.00%> (-0.09%) ⬇️
check_version_ur8long-5.25.1 11.23% <0.00%> (+<0.01%) ⬆️
python_scripts 75.90% <ø> (ø)
start_ursim 85.62% <ø> (-0.94%) ⬇️
ur20-latest ?
ur5-3.14.3 76.17% <88.88%> (-0.08%) ⬇️
ur5e-10.11.0 70.59% <88.88%> (-0.19%) ⬇️
ur5e-10.12.0 71.93% <88.88%> (+0.04%) ⬆️
ur5e-10.7.0 70.40% <88.88%> (-0.04%) ⬇️
ur5e-5.9.4 76.57% <88.88%> (-0.06%) ⬇️
ur7e-10.13.0 72.70% <88.88%> (?)
ur7e-10.14.0 72.96% <88.88%> (+0.05%) ⬆️

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The build references a missing source file, and generated text is passed unsafely as a printf format string.

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

Pull request overview

Adds human-readable error-code logging using generated upstream data and runtime overrides.

Changes:

  • Adds error-text generation, lookup, and override infrastructure.
  • Enhances ErrorCodeMessage::toString() and logging.
  • Adds tests, CMake targets, and nightly version monitoring.
File summaries
File Description
CMakeLists.txt Registers override source and generator targets.
.github/workflows/check_error_codes.yml Checks upstream error-code versions nightly.
include/ur_client_library/primary/primary_consumer.h Logs formatted error-code descriptions.
include/ur_client_library/ur/error_code_overrides.h Declares dynamic override API.
include/ur_client_library/ur/error_code_texts.h Provides generated error-text lookup data.
scripts/error_code_overrides.json Defines static local overrides.
scripts/generate_error_codes.py Generates and verifies the lookup header.
src/primary/robot_message/error_code_message.cpp Implements prioritized text lookup.
tests/CMakeLists.txt Registers the new tests.
tests/test_error_code_message.cpp Tests lookup, overrides, and fallback behavior.
Review details

Suppressed comments (1)

include/ur_client_library/primary/primary_consumer.h:139

  • toString() can now contain text from the JSON/overlay, including %. Passing that text directly as the printf-style format string makes vsnprintf interpret format specifiers without matching arguments, which can corrupt output or invoke undefined behavior. Pass the message through a constant %s format; the already-computed code.to_string can also avoid invoking the override twice.
    const auto log_contents = pkg.toString();

    switch (code.report_level)
    {
      case ReportLevel::DEBUG:
  • Files reviewed: 9/10 changed files
  • Comments generated: 7
  • Review effort level: Balanced

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

Comment thread CMakeLists.txt
Comment thread .github/workflows/check_error_codes.yml Outdated
Comment thread scripts/generate_error_codes.py
Comment thread scripts/generate_error_codes.py Outdated
Comment thread .github/workflows/check_error_codes.yml Outdated
Comment thread scripts/generate_error_codes.py Outdated
Comment thread tests/test_error_code_message.cpp Outdated
urfeex and others added 3 commits September 4, 2026 07:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Dynamic text is used as a format string, and the update workflow cannot recover reliably from closed unmerged PRs.

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

Review details

Suppressed comments (1)

include/ur_client_library/ur/error_code_overrides.h:64

  • This second implementation reference also points to the nonexistent src/primary/robot_message/error_code_overrides.cpp rather than the new source file.
 * Implement additional cases in
 * src/primary/robot_message/error_code_overrides.cpp.
  • Files reviewed: 10/11 changed files
  • Comments generated: 4
  • Review effort level: Balanced

Comment thread include/ur_client_library/primary/primary_consumer.h
Comment thread .github/workflows/check_error_codes.yml
Comment thread include/ur_client_library/ur/error_code_overrides.h Outdated
Comment thread scripts/error_code_overrides.json Outdated
urfeex and others added 2 commits September 4, 2026 08:15
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Out-of-range modes can be misreported, generator escaping is incomplete, and generated documentation needs correction.

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

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

scripts/generate_error_codes.py:91

  • This escaping routine leaves NUL, backspace, form-feed, and other controls embedded raw in the generated C++ source. An escaped JSON \u0000 additionally truncates the displayed const char* text at runtime. Escape source controls explicitly and render NUL visibly rather than generating an embedded terminator.

include/ur_client_library/ur/error_code_overrides.h:64

  • This points contributors to a file that does not exist; the implementation added by this PR is src/ur/error_code_overrides.cpp.
 * Implement additional cases in
 * src/primary/robot_message/error_code_overrides.cpp.
  • Files reviewed: 10/11 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/ur/error_code_overrides.cpp
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Valid JSON control characters can currently produce malformed generated C++ source.

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

Review details

Suppressed comments (1)

include/ur_client_library/ur/error_code_overrides.h:64

  • The implementation is actually in src/ur/error_code_overrides.cpp; the documented path points contributors to a nonexistent file.
 * Implement additional cases in
 * src/primary/robot_message/error_code_overrides.cpp.
  • Files reviewed: 10/11 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread scripts/generate_error_codes.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Python compatibility and stale-branch handling can break the maintenance targets and nightly update workflow.

Review details

Suppressed comments (3)

Previously missed (1) — in code that hasn't changed since the last review.

CMakeLists.txt:138

  • This accepts any Python 3 interpreter, but generate_error_codes.py:106 uses PEP 585 built-in generic annotations (dict[...] and tuple[...]), which require Python 3.9+. With Python 3.8 or older, CMake exposes these targets but the script fails during startup. Require 3.9 here, or rewrite the annotations using typing.Dict/typing.Tuple.

include/ur_client_library/ur/error_code_overrides.h:64

  • This points contributors to a nonexistent source path; the implementation added by this PR is src/ur/error_code_overrides.cpp. Following the public API documentation currently leads to the wrong location.
 * Implement additional cases in
 * src/primary/robot_message/error_code_overrides.cpp.

.github/workflows/check_error_codes.yml:90

  • If an update PR is closed without merging, its remote branch remains. A later run sees no open PR, creates a fresh local branch from the default branch, and this plain push is rejected as non-fast-forward, preventing the automation from recreating the update PR. Handle an existing remote branch or closed PR explicitly by reopening/updating it or safely deleting and recreating the branch.
            git push origin "$BRANCH"
  • Files reviewed: 10/11 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@urfeex
urfeex requested a balanced review from Copilot September 4, 2026 08:09
@urfeex urfeex added this to the Release 2.15.1 milestone Sep 4, 2026
Copilot AI review requested due to automatic review settings September 4, 2026 08:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The nightly automation cannot reliably notify or recreate updates across successive upstream releases.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

.github/workflows/check_error_codes.yml:126

  • The duplicate check is global to the label, but this workflow never closes the notification issue after an update is merged. Consequently, after the first update, that old open issue makes every later upstream version skip its notification. Match the issue title/version (as below), or add a success path that closes resolved notification issues.
  • Files reviewed: 10/11 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit ab233af. Configure here.

Comment thread .github/workflows/check_error_codes.yml Outdated
Comment thread scripts/generate_error_codes.py Outdated
Comment thread scripts/generate_error_codes.py Outdated
Copilot AI review requested due to automatic review settings September 4, 2026 09:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The valid C100A-1 case loses its argument identifier, and the update workflow still cannot recover from a stale remote branch.

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

Review details
  • Files reviewed: 10/11 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/primary/robot_message/error_code_message.cpp Outdated
Since C100 can also have -1 as an argument, we cannot ignore it
Copilot AI review requested due to automatic review settings September 4, 2026 09:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Remote version data can inject generated C++, and transient network failures are incorrectly handled as version mismatches.

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

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

.github/workflows/check_error_codes.yml:60

  • This condition treats every failure of the first network-backed check as a version mismatch. If that request fails transiently but the retry in “Extract versions” succeeds and reports equal versions, regeneration produces no change and git commit fails, so the workflow neither opens a PR nor accurately reports an outdated header. Gate this step on the extracted versions actually differing (and ideally apply the same guard to label creation).
  • Files reviewed: 10/11 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread scripts/generate_error_codes.py Outdated
Copilot AI review requested due to automatic review settings September 4, 2026 09:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Bot-generated pull requests will not trigger required workflows when created using GITHUB_TOKEN.

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

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/ur/error_code_overrides.cpp:76

  • The new exception fallback is not exercised: the existing unknown-mode test uses 127, which is rejected by the range check before robotModeString() is called. Add a case such as arg == -2 (inside the numeric range but not a defined RobotMode) to verify this catch path still returns the intended UNKNOWN text.
  • Files reviewed: 10/11 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread .github/workflows/check_error_codes.yml
@urfeex
urfeex requested a review from urrsk September 4, 2026 09:47
Copilot AI review requested due to automatic review settings September 4, 2026 11:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Version validation permits malformed input, and stale update branches can break the nightly automation.

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

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

scripts/generate_error_codes.py:94

  • The generator's network request has no timeout, so an unresponsive upstream can block the CMake target or nightly workflow until the runner's job limit. Set a finite timeout on urlopen so this maintenance path fails promptly and can be retried.

.github/workflows/check_error_codes.yml:96

  • A closed update PR can leave this remote branch behind. Because only open PRs are detected, the next run creates the same branch locally and the push is rejected as non-fast-forward, so automation cannot recreate an update PR for that version. Explicitly handle an existing remote branch/closed PR (for example, reopen and update it or safely delete/recreate the branch).
            git checkout -b "$BRANCH"
  • Files reviewed: 11/12 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread scripts/generate_error_codes.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 4, 2026 11:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The acknowledged stale update-branch failure remains unresolved, and one lookup comment is inaccurate.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/primary/robot_message/error_code_message.cpp:79

  • This note points to the wrong lookup step: an argument of -1 produces the sentinel key in the exact-match lookup above, so execution never reaches this fallback block. Update it to avoid contradicting the test and actual control flow.
  • Files reviewed: 11/12 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

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.

3 participants