Do you want to work on this issue?
You can request for a bounty in order to promote it!
Apps or names cannnot try to open #272
masterX89 posted onGitHub
Basic Info
Windows
System: Windows 10 x64 (19043.1348)
Browser:
- Not have Firefox
- Microsoft Edge 96.0.1054.62
- Chrome 96.0.4664.110
MacOS
- System: MacOS Monterey 12.0.1
- Browser:
- Not have Firefox
- Chrome 97.0.4692.71
- Safari 15.1 (17612.2.9.1.20)
What is expected?
app
Type:
{name: string | string[], arguments?: string[]} | Array<{name: string | string[], arguments: string[]}>
Specify the
name
of the app to open thetarget
with, and optionally, apparguments
.app
can be an array of apps to try to open andname
can be an array of app names to try. If each app fails, the last error will be thrown.
Steps to reproduce
I wrote the following code in the Windows which is consistent with the description in Basic Info. If the description of app api in the options is correct, then the web page will be opened by the chrome browser because there is no firefox browser. But the current situation is that the chrome browser or the msedge browser does not open the web page.
await open("https://google.com", {
app: {
name: ["firefox", "chrome", "msedge"],
},
});
await open("https://google.com", {
app: {
name: ["firefox", "msedge", "chrome"],
},
});
Then I wrote the similar code that change in the MacOS which is consistent with the description in Basic Info, just replaced msedge
with safari
. The browser still does not open the web page.
await open("https://google.com", {
app: {
name: ["firefox", "google chrome", "safari"],
},
});
await open("https://google.com", {
app: {
name: ["firefox", "safari", "google chrome"],
},
});
Analysis
After debugging, I think the problem lies in the pTryEach
function:
const pTryEach = async (array, mapper) => {
let latestError;
for (const item of array) {
try {
return await mapper(item); // eslint-disable-line no-await-in-loop
} catch (error) {
latestError = error;
}
}
throw latestError;
};
The mapper
function calls the baseOpen
function, and no exception is thrown in the baseOpen
function, so the catch
is actually an unreachable statement.
After reading the api of child_process in node.js, I think we should refer to options.stdio to modify childProcessOptions
const childProcessOptions = {
stdio: ['pipe', 'pipe', process.stderr]
};
And add the following code after the statement to throw an exception:
subprocess.stderr.on('error', (error) => {
throw new Error(`stderr: ${error}`);
});
Please confirm whether the bug exists, and I will submit a pr to fix it after confirmation.