Skip to content

Commit

Permalink
Remove last second error classification for postgres serialization er…
Browse files Browse the repository at this point in the history
…rors (#32030)

GitOrigin-RevId: c5b8572190819e668a740f042aa4db3e569825d7
  • Loading branch information
emmaling27 authored and Convex, Inc. committed Dec 7, 2024
1 parent 53667e7 commit 48d285d
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 38 deletions.
6 changes: 4 additions & 2 deletions crates/common/src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,10 @@ impl From<anyhow::Error> for HttpResponseError {
error_code: err.short_msg().to_string().into(),
msg: err.msg().to_string().into(),
};
let trace = err.last_second_classification();
Self { trace, http_error }
Self {
trace: err,
http_error,
}
}
}

Expand Down
34 changes: 0 additions & 34 deletions crates/errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,6 @@ pub trait ErrorMetadataAnyhowExt {
fn wrap_error_message<F>(self, f: F) -> Self
where
F: FnOnce(String) -> String;
fn last_second_classification(self) -> Self;
}

impl ErrorMetadataAnyhowExt for anyhow::Error {
Expand Down Expand Up @@ -795,39 +794,6 @@ impl ErrorMetadataAnyhowExt for anyhow::Error {
let new_msg = f(self.to_string());
self.context(new_msg)
}

/// Escape hatch classification function.
/// Call this near the edge of the system to do a last-second classification
/// on the way out. This is not an ideal place to do error
/// classification. It is much better to do it at the point it is being
/// thrown.
///
/// Reality is that in some cases it's not ergonomic or possible to classify
/// during throw, so leaving ourselves an escape hatch
fn last_second_classification(self) -> Self {
// Each classification here should have a comment explaining why we're doing
// it last second. We'd much rather prefer doing it at the time of throw.

let as_string = self.to_string();
// Just doing this as a quick hack because sqlx::query has 100 throw sites.
// Ideally, we would wrap sqlx and do handling there, but punting to save time.
let postgres_occs = [
"could not serialize access due to read/write dependencies among transactions",
"could not serialize access due to concurrent update",
];
if let Some(occ) = postgres_occs
.into_iter()
.find(|occ| as_string.contains(occ))
{
// Classify postgres occ as overloaded. ErrorMetadata::OCC is specific to the
// application level inside convex backend.
return self
.context(ErrorMetadata::overloaded("PostgresOcc", occ))
.context(as_string);
}

self
}
}

pub const INTERNAL_SERVER_ERROR_MSG: &str = "Your request couldn't be completed. Try again later.";
Expand Down
3 changes: 1 addition & 2 deletions crates/local_backend/src/subs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,7 @@ async fn run_sync_socket(

let close_msg = match result {
Ok(..) => None,
Err(err) => {
let mut err = err.last_second_classification();
Err(mut err) => {
// Send a message on the WebSocket before closing it if the sync
// worker failed with a "4xx" type error. In this case the client will
// assume the error is its fault and not retry.
Expand Down

0 comments on commit 48d285d

Please sign in to comment.