amodm/webbrowser-rs

xdg-open return value not respected

Nachtalb opened this issue · 2 comments

If xdg-open exists on a system but fails at opening a browser, the fallbacks are not tried.

Steps to reproduce:

  1. For testing purposes, add an xdg-open command to your path that does exit 1.
  2. Launch the tests, and they will fail

Problem

The run_command function accepts the parameter background: bool:

fn run_command(cmd: &mut Command, background: bool, options: &BrowserOptions) -> Result<()> {

This enables us to run the command in the background in a newly spawned child process.

webbrowser-rs/src/unix.rs

Lines 226 to 229 in 6afaa97

cmd
}
.spawn()
.map(|_| ())

Meaning it does not block the execution of the current program.

However, because we don't block the execution of our thread, we won't know about the success of the execution - thus, we will never try any fallbacks, as it'll always be called a success, whether it is or not.

Case where this can happen in the wild

I am running windows and developing inside a WSL machine. There I have xdg-open installed, though it does not support WSL.
Though this is not the case for all WSL machines, it seems. I am running two different distros, and in one, xdg-open does open the browser and everything else, while in the other, it doesn't - not that this is special for the Linux world ..... anyway.

Possible solutions

On the client side:

  • Use something like wsl-open or xdg-open-wsl.
  • Make it work in other ways, like on one of my WSL machines through magic (I have no idea what config is different)
  • Uninstall xdg-open (though it's shipped through xdg-utils and other packages that may require it)

On webbrowser-rs's side

  • Try through one of the alternative methods first. They are all rather specific, whereas xdg-open is quite widely used and thus more general. As I don't know the quality of the other tools, it's hard to say for me that is, whether or not they are viable alternatives on systems that have both installed.
  • Add the background: bool to the BrowserOptions so that one can set it manually and enforce command exit code check, resulting in a proper fallback chain
amodm commented

This is trickier than it seems. There are a few corner cases where xdg-open, or another underlying command blocks execution until the browser is closed. This is why xdg-open (until v0.8.2) was started as a background process.

The side effect of this approach is that because we don't know in what scenario blocking would happen, we can't wait for the child to finish, so technically, we cannot know the exit code of the child. The assumption made during this choice was that if the command exists, it's assumed to succeed.

In the latest main branch of this code, xdg-open is no more used, instead the xdg configuration is parsed to determine the underlying command. I just tested the main branch on WSL2 (Ubuntu) and it seems to work, so long as you have wslu installed. Could the wslu installation be the difference between where it's working on one of your machines, and on another it doesn't?

amodm commented

@Nachtalb, I'm closing this issue. If there are other compelling reasons now, or discovered later, to change this behaviour, this can be reopened.