Skip to content

Commit 7887f1d

Browse files
committed
Improve error handling
1 parent 53674d0 commit 7887f1d

File tree

4 files changed

+40
-9
lines changed

4 files changed

+40
-9
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libsql-storage-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
2727
async-trait = "0.1.80"
2828
serde = "1.0.203"
2929
thiserror = "1.0.61"
30+
prost = "0.12.6"
3031

3132
[features]
3233
foundation-db = ["foundationdb"]
Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use tonic::Status;
1+
use libsql_storage::rpc;
2+
use prost::Message;
3+
use tonic::{Code, Status};
24

35
#[derive(Debug, thiserror::Error)]
46
pub enum Error {
@@ -8,11 +10,34 @@ pub enum Error {
810
Other(#[from] anyhow::Error),
911
}
1012

13+
impl Error {
14+
fn code(&self) -> rpc::ErrorCode {
15+
match self {
16+
Error::WriteConflict => rpc::ErrorCode::WriteConflict,
17+
Error::Other(_) => rpc::ErrorCode::InternalError,
18+
}
19+
}
20+
}
21+
1122
impl From<Error> for Status {
1223
fn from(error: Error) -> Self {
13-
match error {
14-
Error::WriteConflict => Status::aborted("write conflict"),
15-
Error::Other(err) => Status::internal(err.to_string()),
24+
let status_code = match error.code() {
25+
rpc::ErrorCode::InternalError => Code::Internal,
26+
rpc::ErrorCode::WriteConflict => Code::Aborted,
27+
};
28+
let details = rpc::ErrorDetails {
29+
message: error.to_string(),
30+
code: error.code() as i32,
31+
};
32+
33+
let mut details_buf = Vec::new();
34+
if let Err(e) = details.encode(&mut details_buf) {
35+
Status::new(
36+
Code::Internal,
37+
format!("failed to encode error details: {}", e),
38+
)
39+
} else {
40+
Status::with_details(status_code, error.to_string(), details_buf.into())
1641
}
1742
}
1843
}

libsql-storage/src/lib.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ use std::path::Path;
66
use std::sync::{Arc, Mutex};
77

88
use crate::local_cache::LocalCache;
9-
use crate::rpc::Frame;
9+
use crate::rpc::{ErrorCode, Frame};
1010
use libsql_sys::ffi::{SQLITE_ABORT, SQLITE_BUSY};
1111
use libsql_sys::name::{NamespaceName, NamespaceResolver};
1212
use libsql_sys::rusqlite;
1313
use libsql_sys::wal::{Result, Vfs, Wal, WalManager};
14+
use prost::Message;
1415
use rpc::storage_client::StorageClient;
1516
use tonic::transport::Channel;
1617
use tracing::{error, trace, warn};
@@ -365,10 +366,13 @@ impl Wal for DurableWal {
365366
let resp = binding.insert_frames(req);
366367
let resp = tokio::task::block_in_place(|| rt.block_on(resp));
367368
if let Err(e) = resp {
368-
if e.code() == tonic::Code::Aborted {
369-
return Err(rusqlite::ffi::Error::new(SQLITE_BUSY));
370-
}
371-
return Err(rusqlite::ffi::Error::new(SQLITE_ABORT));
369+
let error_code = rpc::ErrorDetails::decode(e.details())
370+
.ok()
371+
.and_then(|details| rpc::ErrorCode::try_from(details.code).ok());
372+
return match error_code {
373+
Some(ErrorCode::WriteConflict) => Err(rusqlite::ffi::Error::new(SQLITE_BUSY)),
374+
_ => Err(rusqlite::ffi::Error::new(SQLITE_ABORT)),
375+
};
372376
}
373377
// TODO: fix parity with storage server frame num with local cache
374378
self.local_cache

0 commit comments

Comments
 (0)