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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# OpenFlow

Current version: `1.3.040`
Current version: `1.3.044`

OpenFlow is a desktop voice dictation app for Windows and macOS built with Electron on the UI layer and Faster-Whisper for local transcription.

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "openflow",
"productName": "OpenFlow",
"version": "1.3.043",
"version": "1.3.044",
"description": "Cross-platform desktop dictation app OpenFlow using Electron and Faster-Whisper.",
"main": "src/main/main.js",
"scripts": {
"start": "electron .",
"check": "node --check src/main/main.js && node --check src/main/preload.js && node --check src/main/overlay-preload.js && node --check src/renderer/renderer.js && node --check src/renderer/overlay.js",
"test:startup-error-isolation": "node scripts/test-startup-error-isolation.js",
"test:duck-restore": "node scripts/test-duck-restore.js",
"build:icons": "node scripts/build-icons.js",
"build:python": "node scripts/build-python.js",
Expand Down
43 changes: 43 additions & 0 deletions scripts/test-startup-error-isolation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

const assert = require('assert');
const fs = require('fs');
const path = require('path');

const mainPath = path.join(__dirname, '..', 'src', 'main', 'main.js');
const source = fs.readFileSync(mainPath, 'utf8');

function getFunctionSource(name) {
const marker = `async function ${name}(`;
const start = source.indexOf(marker);
assert.notStrictEqual(start, -1, `${name} was not found in main.js`);

const bodyStart = source.indexOf('{', start);
let depth = 0;
for (let index = bodyStart; index < source.length; index += 1) {
if (source[index] === '{') depth += 1;
if (source[index] === '}') depth -= 1;
if (depth === 0) return source.slice(start, index + 1);
}

throw new Error(`Could not parse ${name} from main.js`);
}

const refreshSource = getFunctionSource('refreshOpenRouterModels');
const catchMatch = refreshSource.match(/catch\s*\(error\)\s*{([\s\S]*?)\n\s*}/);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Catch-block regex may miss content after the first inner brace

The non-greedy [\s\S]*? terminates at the first \n\s*} encountered inside the catch block — currently the closing brace of the setState({…}) call. Any code added after that inner } (e.g. a second setState({ error: … })) would fall outside catchMatch[1], so the negative assertion on line 40 would silently pass even if the bug were re-introduced in that form. Using a greedy [\s\S]* instead (and anchoring the close to the last } before the end of refreshSource) would capture the entire catch body reliably.

Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/test-startup-error-isolation.js
Line: 27

Comment:
**Catch-block regex may miss content after the first inner brace**

The non-greedy `[\s\S]*?` terminates at the first `\n\s*}` encountered inside the catch block — currently the closing brace of the `setState({…})` call. Any code added after that inner `}` (e.g. a second `setState({ error: … })`) would fall outside `catchMatch[1]`, so the negative assertion on line 40 would silently pass even if the bug were re-introduced in that form. Using a greedy `[\s\S]*` instead (and anchoring the close to the last `}` before the end of `refreshSource`) would capture the entire catch body reliably.

How can I resolve this? If you propose a fix, please make it concise.


assert(catchMatch, 'refreshOpenRouterModels must handle fetch failures');
assert(
/openRouterModelsStatus\s*:\s*'error'/.test(catchMatch[1]),
'OpenRouter failures must remain visible in the cloud-model settings',
);
assert(
/openRouterModelsError\s*:/.test(catchMatch[1]),
'OpenRouter failures must be stored in openRouterModelsError',
);
assert(
!/(^|\n)\s*error\s*:/.test(catchMatch[1]),
'An optional OpenRouter lookup must not overwrite the dictation engine error',
);

console.log('PASS: OpenRouter startup fetch failures are isolated from the dictation engine state.');
1 change: 0 additions & 1 deletion src/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1794,7 +1794,6 @@ async function refreshOpenRouterModels() {
setState({
openRouterModelsStatus: 'error',
openRouterModelsError: String((error && error.message) || error),
error: String((error && error.message) || error),
});
}

Expand Down
Loading