Skip to content

Commit 5e2dfdf

Browse files
committed
refactor: Use serde-error to serialize error with proper backtrace in client/server boundary
1 parent 1ed2ef8 commit 5e2dfdf

File tree

8 files changed

+54
-16
lines changed

8 files changed

+54
-16
lines changed

Cargo.lock

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lact-client/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,10 @@ impl<'a, T: Deserialize<'a>> ResponseBuffer<T> {
218218
.context("Could not deserialize response from daemon")?;
219219
match response {
220220
Response::Ok(data) => Ok(data),
221-
Response::Error(err) => Err(anyhow!("Got error from daemon: {err}")),
221+
Response::Error(err) => {
222+
Err(anyhow::Error::new(err)
223+
.context("Got error from daemon, end of client boundary"))
224+
}
222225
}
223226
}
224227
}

lact-daemon/src/server/gpu_controller/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -651,9 +651,9 @@ impl GpuController {
651651
}
652652
} else if let Ok(hw_mon) = self.first_hw_mon() {
653653
if let Ok(default_cap) = hw_mon.get_power_cap_default() {
654-
hw_mon
655-
.set_power_cap(default_cap)
656-
.with_context(|| format!("Failed to set power cap to default cap: {default_cap}"))?;
654+
hw_mon.set_power_cap(default_cap).with_context(|| {
655+
format!("Failed to set power cap to default cap: {default_cap}")
656+
})?;
657657
}
658658
}
659659

lact-daemon/src/server/handler.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,11 @@ impl<'a> Handler {
164164
Err(apply_err) => {
165165
error!("could not apply settings: {apply_err:?}");
166166
match controller.apply_config(&gpu_config).await {
167-
Ok(()) => Err(apply_err.context("Could not apply settings")),
168-
Err(err) => Err(anyhow!("Could not apply settings, and could not reset to default settings: {err:?}")),
169-
}
167+
Ok(()) => Err(apply_err.context("Could not apply settings")),
168+
Err(err) => Err(apply_err.context(err.context(
169+
"Could not apply settings, and could not reset to default settings",
170+
))),
171+
}
170172
}
171173
}
172174
}

lact-daemon/src/server/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ pub async fn handle_stream(stream: UnixStream, handler: Handler) -> anyhow::Resu
5858
let response = match maybe_request {
5959
Ok(request) => match handle_request(request, &handler).await {
6060
Ok(response) => response,
61-
Err(error) => serde_json::to_vec(&Response::<()>::Error(format!("{error:?}")))?,
61+
Err(error) => serde_json::to_vec(&Response::<()>::from(error))?,
6262
},
63-
Err(error) => serde_json::to_vec(&Response::<()>::Error(format!(
64-
"Failed to deserialize request: {error}"
65-
)))?,
63+
Err(error) => serde_json::to_vec(&Response::<()>::from(
64+
anyhow::Error::new(error).context("Failed to deserialize"),
65+
))?,
6666
};
6767

6868
stream.write_all(&response).await?;

lact-schema/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ args = ["clap"]
1010
amdgpu-sysfs = { workspace = true }
1111
serde = { workspace = true }
1212
serde_with = { workspace = true }
13+
serde-error = "=0.1.2"
14+
anyhow = { workspace = true }
1315

1416
indexmap = { version = "*", features = ["serde"] }
1517
clap = { version = "4.4.18", features = ["derive"], optional = true }

lact-schema/src/response.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
use serde::{Deserialize, Serialize};
22

3-
#[derive(Serialize, Deserialize, Debug, Clone)]
3+
#[derive(Serialize, Deserialize, Debug)]
44
#[serde(tag = "status", content = "data", rename_all = "snake_case")]
55
pub enum Response<T> {
66
Ok(T),
7-
Error(String),
7+
Error(serde_error::Error),
8+
}
9+
10+
impl<T> From<anyhow::Error> for Response<T> {
11+
fn from(value: anyhow::Error) -> Self {
12+
Response::Error(serde_error::Error::new(&*value))
13+
}
814
}

lact-schema/src/tests.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{Pong, Request, Response};
2+
use anyhow::anyhow;
23
use serde_json::json;
34

45
#[test]
@@ -35,11 +36,24 @@ fn controllers_response() {
3536
#[test]
3637
fn error_response() {
3738
let expected_response = json!({
38-
"status": "error",
39-
"data": "my super error"
39+
"data": {
40+
"description": "third deeper context",
41+
"source": {
42+
"description": "second context",
43+
"source": {
44+
"description": "first error",
45+
"source": null
46+
}
47+
}
48+
},
49+
"status": "error"
4050
});
4151

42-
let response = Response::<()>::Error("my super error".to_owned());
52+
let error = anyhow!("first error")
53+
.context("second context")
54+
.context(anyhow!("third deeper context"));
55+
56+
let response = Response::<()>::from(error);
4357

4458
assert_eq!(serde_json::to_value(response).unwrap(), expected_response);
4559
}

0 commit comments

Comments
 (0)