Skip to content

Plot::show() panics when no opener binary exists, and silently no-ops when it fails #435

Description

@grische

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:

  1. 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

  2. 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.

Metadata

Metadata

Assignees

No one assigned

    标签

    No labels
    No labels

    Type

    No type

    项目

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions