Skip to content
Closed
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
27 changes: 24 additions & 3 deletions dstack/vmm/src/main_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::ops::Deref;
use std::path::{Component, Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};

use anyhow::{bail, Context, Result};
use anyhow::{anyhow, bail, Context, Result};
use dstack_types::AppCompose;
use dstack_vmm_rpc as rpc;
use dstack_vmm_rpc::vmm_server::{VmmRpc, VmmServer};
Expand Down Expand Up @@ -41,6 +41,15 @@ pub struct RpcHandler {
app: App,
}

/// Flatten an anyhow error chain before it crosses the RPC boundary.
///
/// Some pRPC transports only retain an error's `Display` representation. An
/// outer context such as "Failed to start VM" would otherwise hide the GPU
/// reset failure that operators need to diagnose the request.
fn rpc_error(context: &str, error: anyhow::Error) -> anyhow::Error {
anyhow!("{context}: {error:#}")
}
Comment on lines +49 to +51

impl Deref for RpcHandler {
type Target = App;

Expand Down Expand Up @@ -580,7 +589,7 @@ impl VmmRpc for RpcHandler {
if let Err(err) = fs::remove_dir_all(&work_dir) {
warn!("Failed to remove work dir: {}", err);
}
return Err(err);
return Err(rpc_error("Failed to create VM", err));
}

Ok(Id { id })
Expand All @@ -590,7 +599,7 @@ impl VmmRpc for RpcHandler {
self.app
.start_vm(&request.id)
.await
.context("Failed to start VM")?;
.map_err(|error| rpc_error("Failed to start VM", error))?;
Ok(())
}

Expand Down Expand Up @@ -1064,6 +1073,18 @@ mod tests {
use super::*;
use rocket::figment::Figment;

#[test]
fn rpc_error_preserves_the_full_error_chain_in_display() {
let error = anyhow!("PCI config write failed")
.context("failed to sanitize GPU using bridge 0000:00:01.0");
let error = rpc_error("Failed to start VM", error);

assert_eq!(
error.to_string(),
"Failed to start VM: failed to sanitize GPU using bridge 0000:00:01.0: PCI config write failed"
);
}

fn test_cvm_config() -> CvmConfig {
let config: crate::config::Config = Figment::from(crate::config::load_config_figment(None))
.extract()
Expand Down
Loading