Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
* text=auto

*.fig binary
*.mat binary
*.mdl binary diff merge=mlAutoMerge
*.mex* binary
*.mlapp binary
*.mldatx binary merge=mlAutoMerge
*.mlproj binary
*.mlx binary
*.p binary
*.plprj binary
*.psprjx binary merge=mlAutoMerge
*.sbproj binary
*.sfx binary
*.sldd binary
*.slreqx binary merge=mlAutoMerge
*.slmx binary merge=mlAutoMerge
*.sltx binary
*.slxc binary
*.slx binary merge=mlAutoMerge
*.slxp binary

## MATLAB Project metadata files use LF line endings
/resources/project/**/*.xml text eol=lf

## Other common binary file types
*.docx binary
*.exe binary
*.jpg binary
*.pdf binary
*.png binary
*.xlsx binary
24 changes: 24 additions & 0 deletions .github/workflows/matlab-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: MATLAB Tests

on:
push:
branches:
- main
pull_request:

jobs:
test:
name: Run MATLAB Tests
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up MATLAB
uses: matlab-actions/setup-matlab@v2

- name: Run tests
uses: matlab-actions/run-tests@v2
with:
source-folder: src
test-results-junit: test-results.xml
40 changes: 40 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Autosave files
*.asv
*.m~
*.autosave
*.slx.r*
*.mdl.r*

# Derived content-obscured files
*.p

# Compiled MEX files
*.mex*

# Packaged app and toolbox files
*.mlappinstall
*.mltbx

# Deployable archives
*.ctf

# Generated helpsearch folders
helpsearch*/

# Code generation folders
slprj/
sccprj/
codegen/

# Cache files
*.slxc

# Cloud based storage dotfile
.MATLABDriveTag

# buildtool cache folder
.buildtool/

# SimBiology backup files
*.sbproj.backup
*.sbproj.bak
42 changes: 21 additions & 21 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,19 @@ uihtml-console-rerouter/
├── README.md
├── LICENSE
├── src/
│ ├── ConsoleErrorRerouter.m ← main MATLAB class
│ └── js/
│ └── consoleShim.js ← JavaScript error interceptor snippet
├── toolbox/ ← packageable toolbox content
│ ├── ConsoleErrorRerouter.m ← main MATLAB class (includes inlined shim)
│ ├── Contents.m ← toolbox summary for 'help'
│ └── examples/
│ ├── basic_usage.m ← minimal working example
│ ├── custom_formatting.m ← example using formatting options
│ └── html/
│ └── example_page.html
├── examples/
│ ├── basic_usage.m ← minimal working example
│ ├── custom_formatting.m ← example using formatting options
│ └── html/
│ └── example_page.html ← sample HTML file used by examples
└── tests/
├── tConsoleErrorRerouter.m ← MATLAB unit tests (matlab.unittest)
└── tests/ ← unit tests (infrastructure)
├── tConsoleErrorRerouter.m
└── html/
└── test_page.html ← HTML fixture used by tests
└── test_page.html
```

---
Expand All @@ -72,21 +70,22 @@ uihtml-console-rerouter/
[uihtml docs page](https://www.mathworks.com/help/matlab/ref/uihtml.html)).
Do not use language features introduced after R2023a without a version guard.

### JavaScript
### JavaScript (Inlined Shim)
- **ES5 compatible** — the embedded browser in older MATLAB releases may not
support ES6+ syntax. Use `var`, not `let`/`const`. Use function declarations,
not arrow functions.
- Keep `consoleShim.js` self-contained with no external dependencies.
- The shim must call `window.sendEventToMATLAB` using the reserved event name
`"ConsoleError"` and pass a plain object `{ level, message, stack }`.
- The shim must be self-contained and is injected into the HTML as a `<script>`
block during construction of `ConsoleErrorRerouter`.
- The shim must call `htmlComponent.sendEventToMATLAB` using the reserved event
name `"ConsoleError"` and pass a plain object `{ level, message, stack }`.
- Do not rename or repurpose the `"ConsoleError"` event name — the MATLAB class
filters on this string.

### HTML examples / fixtures
- Keep example HTML files minimal — their purpose is to demonstrate the shim, not
showcase web design.
- Include the shim via an inline `<script>` block, not a separate file reference,
so the HTML is self-contained.
- **Requirement**: Every HTML file must define a global `setup(htmlComponent)`
function for the shim to correctly hook into the bidirectional communication bridge.

---

Expand All @@ -98,7 +97,7 @@ uihtml-console-rerouter/
|---|---|---|
| `ConsoleErrorRerouter(uihtmlComp)` | Constructor | Accepts a `matlab.ui.control.HTML` object. Registers the internal `HTMLEventReceived` callback. |
| `Enabled` | Property (`logical`) | Toggles rerouting on/off without destroying the object. Default: `true`. |
| `ErrorLevels` | Property (`string` array) | Console levels to intercept. Default: `["error"]`. Allowed: `"error"`, `"warn"`, `"info"`, `"log"`. |
| `ErrorLevels` | Property (`string` array) | Console levels to intercept. Default: `["error"]`. Allowed: `"error"`, `"warn"`, `"info"`, `"log"`, `"debug"`. |
| `FormatFcn` | Property (`function_handle`) | Custom formatter `f(level, message, stack) → char`. Default: built-in red-text formatter using `fprintf`. |
| `delete()` | Destructor | Unregisters only the rerouter's listener; preserves any other `HTMLEventReceived` listeners on the component. |

Expand Down Expand Up @@ -132,7 +131,8 @@ uihtml-console-rerouter/
- Introduce any new MATLAB toolbox dependency (the tool must run on MATLAB base
with no additional toolboxes).
- Use `evalin`, `evalc`, or `eval` anywhere in MATLAB code.
- Modify `consoleShim.js` to use ES6+ syntax without a compatibility gate.
- Modify the inlined shim logic in `ConsoleErrorRerouter.m` to use ES6+ syntax
without a compatibility gate.
- Remove or rename any public property or method listed in the Key Interfaces table.
- Add files outside the directory structure defined above without updating this
AGENTS.md and the README.
Expand Down
91 changes: 74 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,74 @@
UIHTML Console Error Rerouter
This project provides a robust solution for seamlessly integrating JavaScript console errors from MATLAB's uihtml components directly into the MATLAB command window. This allows developers to centralize their debugging efforts and gain immediate visibility into front-end issues without needing to inspect the browser's developer console separately.
Desired Behavior
The primary goal of this tool is to bridge the communication gap between the web content displayed in a uihtml component and the MATLAB environment. Specifically, when an error occurs within the JavaScript execution of a uihtml component, it should be:
* Captured automatically: Errors that would normally appear in the browser's console should be intercepted.
* Rerouted to the MATLAB Command Window: These captured errors should then be displayed prominently in the MATLAB command window, ideally in a format that distinguishes them from standard MATLAB output.
* Non-intrusive: The rerouting mechanism should not interfere with other HTMLEventReceived events that the user might be handling for different purposes. Only console errors should trigger the rerouting behavior.
* Easy to integrate: The solution should involve minimal setup, requiring a simple inclusion in the HTML file and an easy-to-use MATLAB class.
Future Improvements
This foundational setup offers several avenues for enhancement:
* Configurable Error Levels: Allow users to specify which types of console messages (e.g., console.warn, console.info) should be rerouted.
* Customizable Output Formatting: Provide options for users to define how error messages are displayed in the MATLAB command window.
* Error Categorization: Implement more sophisticated parsing to categorize and filter errors based on their source or type.
* Asynchronous Error Handling: Explore mechanisms for handling errors that occur asynchronously within the uihtml component.
* Integration with Logging Frameworks: Enable the rerouter to hook into existing MATLAB logging frameworks for more comprehensive error management.
Feel free to expand upon this foundation to meet more specific project requirements and enhance the debugging experience.

# UIHTML Console Error Rerouter

A robust solution for seamlessly integrating JavaScript console messages from MATLAB's `uihtml` components directly into the MATLAB Command Window. This tool centralizes your debugging efforts and gains immediate visibility into front-end issues without needing to inspect the browser's developer console separately.

---

## How It Works

1. **MATLAB Class (`ConsoleErrorRerouter`)**: A simple class that wraps a `uihtml` component and listens for custom console events.
2. **Inlined Shim Injection**: On construction, the class creates a temporary copy of your HTML file with an inlined JavaScript shim injected at the end of the `<body>`.
3. **Setup Hook**: The shim automatically wraps your global `setup(htmlComponent)` function to capture the internal MATLAB component reference, allowing it to send messages back via `sendEventToMATLAB`.

---

## Getting Started

### 1. Requirements

For the rerouting to work, your HTML file **must** define a global `setup(htmlComponent)` function. This is the standard pattern for bidirectional communication in MATLAB `uihtml`.

```javascript
// index.html
function setup(htmlComponent) {
// Your application logic here
console.log("Application is ready!");
}
```

### 2. Basic Usage

Attach the rerouter to your `uihtml` component in MATLAB.

```matlab
fig = uifigure;
h = uihtml(fig);
h.HTMLSource = 'index.html';

% Create the rerouter
rerouter = ConsoleErrorRerouter(h);

% Optional: Configure which levels to intercept (default is just ["error"])
rerouter.ErrorLevels = ["error", "warn", "info", "log", "debug"];
```

---

## Features

* **Configurable Error Levels**: Intercept `error`, `warn`, `info`, `log`, and `debug` messages.
* **Custom Formatters**: Provide your own function handle to format the output.
* **Non-Intrusive**: Uses `addlistener` to ensure it doesn't clobber any existing `HTMLEventReceivedFcn` or other event handlers you have registered.
* **Clean Output**: Suppresses internal MATLAB backtraces for warnings to provide focused, relevant debugging information.
* **Automatic Cleanup**: Destroys temporary files and restores the original `HTMLSource` when the object is deleted.

---

## Running Examples

Explore the `examples/` directory for ready-to-run scripts:

* `basic_usage.m`: Simple demonstration of rerouting all console levels.
* `custom_formatting.m`: Demonstrates how to use a custom function to format the rerouted messages.

---

## Testing

The project includes unit tests built with the `matlab.unittest` framework to verify the rerouter's behavior, including shim injection and message filtering.

To run the tests:
```matlab
results = runtests("tests/tConsoleErrorRerouter.m");
disp(results);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="1" type="DIR_SIGNIFIER"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="workflows" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info Name="Test" ReadOnly="READ_ONLY"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="test" type="Label"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info Name="Other" ReadOnly="READ_ONLY"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="other" type="Label"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info Name="Convenience" ReadOnly="READ_ONLY"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="convenience" type="Label"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info Name="None" ReadOnly="READ_ONLY"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="none" type="Label"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info Name="Derived" ReadOnly="READ_ONLY"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="derived" type="Label"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info Name="Design" ReadOnly="READ_ONLY"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="design" type="Label"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info Name="Artifact" ReadOnly="READ_ONLY"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="artifact" type="Label"/>
2 changes: 2 additions & 0 deletions resources/project/Project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info MetadataType="fixedPathV2"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="1" type="DIR_SIGNIFIER"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="artifact"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="test_page.html" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info DataType="None" Name="Classification" ReadOnly="1" SingleValued="1"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="FileClassCategory" type="Category"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="1" type="DIR_SIGNIFIER"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="MockHTMLEventData.m" type="File"/>
Loading
Loading