diff --git a/libs/user-facing-errors/src/lib.rs b/libs/user-facing-errors/src/lib.rs index ce870a55ab4f..c2a0311cb0ab 100644 --- a/libs/user-facing-errors/src/lib.rs +++ b/libs/user-facing-errors/src/lib.rs @@ -68,6 +68,9 @@ pub struct Error { is_panic: bool, #[serde(flatten)] inner: ErrorType, + + #[serde(skip_serializing_if = "Option::is_none")] + batch_request_idx: Option, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] @@ -100,6 +103,7 @@ impl Error { backtrace: Some(format!("{:?}", backtrace::Backtrace::new())), }), is_panic: false, + batch_request_idx: None, } } @@ -110,6 +114,7 @@ impl Error { backtrace: None, }), is_panic: false, + batch_request_idx: None, } } @@ -135,6 +140,7 @@ impl Error { backtrace, }), is_panic: true, + batch_request_idx: None, } } @@ -143,6 +149,7 @@ impl Error { Error { inner: ErrorType::Known(err), is_panic: false, + batch_request_idx: None, } } @@ -155,6 +162,7 @@ impl Error { backtrace: None, }), is_panic: true, + batch_request_idx: None, } } @@ -172,6 +180,10 @@ impl Error { err @ ErrorType::Unknown(_) => panic!("Expected known error, got {:?}", err), } } + + pub fn set_batch_request_idx(&mut self, batch_request_idx: usize) -> () { + self.batch_request_idx = Some(batch_request_idx) + } } pub fn new_backtrace() -> backtrace::Backtrace { @@ -183,6 +195,7 @@ impl From for Error { Error { inner: ErrorType::Unknown(unknown_error), is_panic: false, + batch_request_idx: None, } } } @@ -192,6 +205,7 @@ impl From for Error { Error { is_panic: false, inner: ErrorType::Known(known_error), + batch_request_idx: None, } } } diff --git a/query-engine/core/src/error.rs b/query-engine/core/src/error.rs index 931d80dffd80..965bee358b4a 100644 --- a/query-engine/core/src/error.rs +++ b/query-engine/core/src/error.rs @@ -70,6 +70,9 @@ pub enum CoreError { #[error("{}", _0)] FieldConversionError(#[from] FieldConversionError), + + #[error("Error in batch request {request_idx}: {error}")] + BatchError { request_idx: usize, error: Box }, } impl CoreError { @@ -269,6 +272,12 @@ impl From for user_facing_errors::Error { .into() } + CoreError::BatchError { request_idx, error } => { + let mut inner_error = user_facing_errors::Error::from(*error); + inner_error.set_batch_request_idx(request_idx); + inner_error + } + _ => user_facing_errors::Error::from_dyn_error(&err), } } diff --git a/query-engine/core/src/executor/execute_operation.rs b/query-engine/core/src/executor/execute_operation.rs index 77819f577508..f49b02841482 100644 --- a/query-engine/core/src/executor/execute_operation.rs +++ b/query-engine/core/src/executor/execute_operation.rs @@ -44,16 +44,25 @@ pub async fn execute_many_operations( let mut results = Vec::with_capacity(queries.len()); - for (query_graph, serializer) in queries { + for (i, (query_graph, serializer)) in queries.into_iter().enumerate() { increment_counter!(PRISMA_CLIENT_QUERIES_TOTAL); let operation_timer = Instant::now(); let interpreter = QueryInterpreter::new(conn); let result = QueryPipeline::new(query_graph, interpreter, serializer) .execute(trace_id.clone()) - .await?; + .await; histogram!(PRISMA_CLIENT_QUERIES_HISTOGRAM_MS, operation_timer.elapsed()); - results.push(Ok(result)); + + match result { + Ok(result) => results.push(Ok(result)), + Err(error) => { + return Err(crate::CoreError::BatchError { + request_idx: i, + error: Box::new(error), + }); + } + } } Ok(results)