Plot::show() offers no way for a caller to handle a failed browser handoff.
Running it on a headless server causes a panic, but the panic message is misleading.
How to reproduce
use plotly::{Plot, Scatter};
fn main() {
let mut plot = Plot::new();
plot.add_trace(Scatter::new(vec![0, 1, 2], vec![0.0, 1.5, 3.0]));
plot.show();
}
Run on a headless Linux host with no xdg-open on PATH 👍
thread 'main' panicked at .../plotly-0.14.1/src/plot.rs:789:14:
Could not find default application for HTML files.
[...]
: Os { code: 2, kind: NotFound, message: "No such file or directory" }
Environment
- plotly 0.14.1
- rustc 1.98.0
- AlmaLinux 9.8
Expected
A library call should not abort the process over a missing external binary. The caller should have
some way to detect this and potentially fall back to write_html() or write_image() on its own or
show a clear error message.
Cause
|
#[cfg(all(unix, not(target_os = "android"), not(target_os = "macos")))] |
|
fn show_with_default_app(temp_path: &str) { |
|
use std::process::Command; |
|
Command::new("xdg-open") |
|
.args([temp_path]) |
|
.output() |
|
.expect(DEFAULT_HTML_APP_NOT_FOUND); |
|
} |
There are two problems with it:
-
Missing binary panics: .output() returns Err only when the process cannot be
spawned, i.e. xdg-open is not on PATH. .expect() turns that into a panic, and
show() returns (), so a caller has nothing to match on.
The resulting error message is very misleading here:
|
const DEFAULT_HTML_APP_NOT_FOUND: &str = r#"Could not find default application for HTML files. |
|
Consider using the `to_html` method obtain a string representation instead. If using the `kaleido` or `plotly_static` feature the |
|
`write_image` method can be used to produce a static image in one of the following formats: |
|
- ImageFormat::PNG |
|
- ImageFormat::JPEG |
|
- ImageFormat::WEBP |
|
- ImageFormat::SVG |
|
- ImageFormat::PDF |
|
- ImageFormat::EPS // will be removed in version 0.15.0 |
-
Return code of the xdg-open is ignored: If xdg-open is installed but exits non-zero
(e.g. when no application is registered for HTML) it still returns Ok, carrying
the failure inside Output::status, but status is never read.
The macOS and Windows variants have a similar shape.
Plot::show()offers no way for a caller to handle a failed browser handoff.Running it on a headless server causes a panic, but the panic message is misleading.
How to reproduce
Run on a headless Linux host with no
xdg-openonPATH👍Environment
Expected
A library call should not abort the process over a missing external binary. The caller should have
some way to detect this and potentially fall back to
write_html()orwrite_image()on its own orshow a clear error message.
Cause
plotly.rs/plotly/src/plot.rs
Lines 793 to 800 in 00fe051
There are two problems with it:
Missing binary panics:
.output()returnsErronly when the process cannot bespawned, i.e.
xdg-openis not onPATH..expect()turns that into a panic, andshow()returns(), so a caller has nothing to match on.The resulting error message is very misleading here:
plotly.rs/plotly/src/plot.rs
Lines 57 to 65 in 00fe051
Return code of the xdg-open is ignored: If
xdg-openis installed but exits non-zero(e.g. when no application is registered for HTML) it still returns
Ok, carryingthe failure inside
Output::status, but status is never read.The macOS and Windows variants have a similar shape.