@@ -29,15 +29,15 @@ use crate::cluster::{ClusterState, NodeRef};
29
29
#[ allow( deprecated) ]
30
30
use crate :: cql_to_rust:: { FromRow , FromRowError } ;
31
31
use crate :: deserialize:: DeserializeOwnedRow ;
32
- use crate :: errors:: { ProtocolError , RequestError } ;
33
- use crate :: errors:: { QueryError , RequestAttemptError } ;
32
+ use crate :: errors:: { RequestAttemptError , RequestError } ;
34
33
use crate :: frame:: response:: result;
35
34
use crate :: network:: Connection ;
36
35
use crate :: observability:: driver_tracing:: RequestSpan ;
37
36
use crate :: observability:: history:: { self , HistoryListener } ;
38
37
use crate :: observability:: metrics:: Metrics ;
39
38
use crate :: policies:: load_balancing:: { self , RoutingInfo } ;
40
39
use crate :: policies:: retry:: { RequestInfo , RetryDecision , RetrySession } ;
40
+ use crate :: prepared_statement:: PartitionKeyError ;
41
41
use crate :: response:: query_result:: ColumnSpecs ;
42
42
use crate :: response:: { NonErrorQueryResponse , QueryResponse } ;
43
43
use crate :: statement:: { prepared_statement:: PreparedStatement , query:: Query } ;
@@ -79,9 +79,7 @@ mod checked_channel_sender {
79
79
use tokio:: sync:: mpsc;
80
80
use uuid:: Uuid ;
81
81
82
- use crate :: errors:: QueryError ;
83
-
84
- use super :: ReceivedPage ;
82
+ use super :: { NextPageError , ReceivedPage } ;
85
83
86
84
/// A value whose existence proves that there was an attempt
87
85
/// to send an item of type T through a channel.
@@ -106,7 +104,7 @@ mod checked_channel_sender {
106
104
}
107
105
}
108
106
109
- type ResultPage = Result < ReceivedPage , QueryError > ;
107
+ type ResultPage = Result < ReceivedPage , NextPageError > ;
110
108
111
109
impl ProvingSender < ResultPage > {
112
110
pub ( crate ) async fn send_empty_page (
@@ -127,12 +125,12 @@ mod checked_channel_sender {
127
125
128
126
use checked_channel_sender:: { ProvingSender , SendAttemptedProof } ;
129
127
130
- type PageSendAttemptedProof = SendAttemptedProof < Result < ReceivedPage , QueryError > > ;
128
+ type PageSendAttemptedProof = SendAttemptedProof < Result < ReceivedPage , NextPageError > > ;
131
129
132
130
// PagerWorker works in the background to fetch pages
133
131
// QueryPager receives them through a channel
134
132
struct PagerWorker < ' a , QueryFunc , SpanCreatorFunc > {
135
- sender : ProvingSender < Result < ReceivedPage , QueryError > > ,
133
+ sender : ProvingSender < Result < ReceivedPage , NextPageError > > ,
136
134
137
135
// Closure used to perform a single page query
138
136
// AsyncFn(Arc<Connection>, Option<Arc<[u8]>>) -> Result<QueryResponse, RequestAttemptError>
@@ -267,7 +265,10 @@ where
267
265
}
268
266
269
267
self . log_request_error ( & last_error) ;
270
- let ( proof, _) = self . sender . send ( Err ( last_error. into_query_error ( ) ) ) . await ;
268
+ let ( proof, _) = self
269
+ . sender
270
+ . send ( Err ( NextPageError :: RequestFailure ( last_error) ) )
271
+ . await ;
271
272
proof
272
273
}
273
274
@@ -477,7 +478,7 @@ where
477
478
/// any complicated logic related to retries, it just fetches pages from
478
479
/// a single connection.
479
480
struct SingleConnectionPagerWorker < Fetcher > {
480
- sender : ProvingSender < Result < ReceivedPage , QueryError > > ,
481
+ sender : ProvingSender < Result < ReceivedPage , NextPageError > > ,
481
482
fetcher : Fetcher ,
482
483
}
483
484
@@ -490,21 +491,22 @@ where
490
491
match self . do_work ( ) . await {
491
492
Ok ( proof) => proof,
492
493
Err ( err) => {
493
- let ( proof, _) = self . sender . send ( Err ( err) ) . await ;
494
+ let ( proof, _) = self
495
+ . sender
496
+ . send ( Err ( NextPageError :: RequestFailure (
497
+ RequestError :: LastAttemptError ( err) ,
498
+ ) ) )
499
+ . await ;
494
500
proof
495
501
}
496
502
}
497
503
}
498
504
499
- async fn do_work ( & mut self ) -> Result < PageSendAttemptedProof , QueryError > {
505
+ async fn do_work ( & mut self ) -> Result < PageSendAttemptedProof , RequestAttemptError > {
500
506
let mut paging_state = PagingState :: start ( ) ;
501
507
loop {
502
- let result = ( self . fetcher ) ( paging_state)
503
- . await
504
- . map_err ( RequestAttemptError :: into_query_error) ?;
505
- let response = result
506
- . into_non_error_query_response ( )
507
- . map_err ( RequestAttemptError :: into_query_error) ?;
508
+ let result = ( self . fetcher ) ( paging_state) . await ?;
509
+ let response = result. into_non_error_query_response ( ) ?;
508
510
match response. response {
509
511
NonErrorResponse :: Result ( result:: Result :: Rows ( ( rows, paging_state_response) ) ) => {
510
512
let ( proof, send_result) = self
@@ -539,10 +541,9 @@ where
539
541
return Ok ( proof) ;
540
542
}
541
543
_ => {
542
- return Err ( ProtocolError :: UnexpectedResponse (
544
+ return Err ( RequestAttemptError :: UnexpectedResponse (
543
545
response. response . to_response_kind ( ) ,
544
- )
545
- . into ( ) ) ;
546
+ ) ) ;
546
547
}
547
548
}
548
549
}
@@ -565,7 +566,7 @@ where
565
566
/// is not the intended target type.
566
567
pub struct QueryPager {
567
568
current_page : RawRowLendingIterator ,
568
- page_receiver : mpsc:: Receiver < Result < ReceivedPage , QueryError > > ,
569
+ page_receiver : mpsc:: Receiver < Result < ReceivedPage , NextPageError > > ,
569
570
tracing_ids : Vec < Uuid > ,
570
571
}
571
572
@@ -583,7 +584,7 @@ impl QueryPager {
583
584
/// borrows from self.
584
585
///
585
586
/// This is cancel-safe.
586
- async fn next ( & mut self ) -> Option < Result < ColumnIterator , QueryError > > {
587
+ async fn next ( & mut self ) -> Option < Result < ColumnIterator , NextRowError > > {
587
588
let res = std:: future:: poll_fn ( |cx| Pin :: new ( & mut * self ) . poll_fill_page ( cx) ) . await ;
588
589
match res {
589
590
Some ( Ok ( ( ) ) ) => { }
@@ -596,15 +597,15 @@ impl QueryPager {
596
597
self . current_page
597
598
. next ( )
598
599
. unwrap ( )
599
- . map_err ( |err| NextRowError :: RowDeserializationError ( err ) . into ( ) ) ,
600
+ . map_err ( NextRowError :: RowDeserializationError ) ,
600
601
)
601
602
}
602
603
603
604
/// Tries to acquire a non-empty page, if current page is exhausted.
604
605
fn poll_fill_page < ' r > (
605
606
mut self : Pin < & ' r mut Self > ,
606
607
cx : & mut Context < ' _ > ,
607
- ) -> Poll < Option < Result < ( ) , QueryError > > > {
608
+ ) -> Poll < Option < Result < ( ) , NextRowError > > > {
608
609
if !self . is_current_page_exhausted ( ) {
609
610
return Poll :: Ready ( Some ( Ok ( ( ) ) ) ) ;
610
611
}
@@ -627,14 +628,11 @@ impl QueryPager {
627
628
fn poll_next_page < ' r > (
628
629
mut self : Pin < & ' r mut Self > ,
629
630
cx : & mut Context < ' _ > ,
630
- ) -> Poll < Option < Result < ( ) , QueryError > > > {
631
+ ) -> Poll < Option < Result < ( ) , NextRowError > > > {
631
632
let mut s = self . as_mut ( ) ;
632
633
633
634
let received_page = ready_some_ok ! ( Pin :: new( & mut s. page_receiver) . poll_recv( cx) ) ;
634
635
635
- // TODO: see my other comment next to QueryError::NextRowError
636
- // This is the place where conversion happens. To fix this, we need to refactor error types in iterator API.
637
- // The `page_receiver`'s error type should be narrowed from QueryError to some other error type.
638
636
let raw_rows_with_deserialized_metadata =
639
637
received_page. rows . deserialize_metadata ( ) . map_err ( |err| {
640
638
NextRowError :: NextPageError ( NextPageError :: ResultMetadataParseError ( err) )
@@ -689,8 +687,8 @@ impl QueryPager {
689
687
execution_profile : Arc < ExecutionProfileInner > ,
690
688
cluster_data : Arc < ClusterState > ,
691
689
metrics : Arc < Metrics > ,
692
- ) -> Result < Self , QueryError > {
693
- let ( sender, receiver) = mpsc:: channel ( 1 ) ;
690
+ ) -> Result < Self , NextRowError > {
691
+ let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , NextPageError > > ( 1 ) ;
694
692
695
693
let consistency = query
696
694
. config
@@ -768,8 +766,8 @@ impl QueryPager {
768
766
769
767
pub ( crate ) async fn new_for_prepared_statement (
770
768
config : PreparedIteratorConfig ,
771
- ) -> Result < Self , QueryError > {
772
- let ( sender, receiver) = mpsc:: channel ( 1 ) ;
769
+ ) -> Result < Self , NextRowError > {
770
+ let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , NextPageError > > ( 1 ) ;
773
771
774
772
let consistency = config
775
773
. prepared
@@ -803,7 +801,9 @@ impl QueryPager {
803
801
) {
804
802
Ok ( res) => res. unzip ( ) ,
805
803
Err ( err) => {
806
- let ( proof, _res) = ProvingSender :: from ( sender) . send ( Err ( err) ) . await ;
804
+ let ( proof, _res) = ProvingSender :: from ( sender)
805
+ . send ( Err ( NextPageError :: PartitionKeyError ( err) ) )
806
+ . await ;
807
807
return proof;
808
808
}
809
809
} ;
@@ -889,8 +889,8 @@ impl QueryPager {
889
889
connection : Arc < Connection > ,
890
890
consistency : Consistency ,
891
891
serial_consistency : Option < SerialConsistency > ,
892
- ) -> Result < Self , QueryError > {
893
- let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , QueryError > > ( 1 ) ;
892
+ ) -> Result < Self , NextRowError > {
893
+ let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , NextPageError > > ( 1 ) ;
894
894
895
895
let page_size = query. get_validated_page_size ( ) ;
896
896
@@ -919,8 +919,8 @@ impl QueryPager {
919
919
connection : Arc < Connection > ,
920
920
consistency : Consistency ,
921
921
serial_consistency : Option < SerialConsistency > ,
922
- ) -> Result < Self , QueryError > {
923
- let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , QueryError > > ( 1 ) ;
922
+ ) -> Result < Self , NextRowError > {
923
+ let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , NextPageError > > ( 1 ) ;
924
924
925
925
let page_size = prepared. get_validated_page_size ( ) ;
926
926
@@ -946,8 +946,8 @@ impl QueryPager {
946
946
947
947
async fn new_from_worker_future (
948
948
worker_task : impl Future < Output = PageSendAttemptedProof > + Send + ' static ,
949
- mut receiver : mpsc:: Receiver < Result < ReceivedPage , QueryError > > ,
950
- ) -> Result < Self , QueryError > {
949
+ mut receiver : mpsc:: Receiver < Result < ReceivedPage , NextPageError > > ,
950
+ ) -> Result < Self , NextRowError > {
951
951
tokio:: task:: spawn ( worker_task) ;
952
952
953
953
// This unwrap is safe because:
@@ -1035,14 +1035,14 @@ impl<RowT> Stream for TypedRowStream<RowT>
1035
1035
where
1036
1036
RowT : DeserializeOwnedRow ,
1037
1037
{
1038
- type Item = Result < RowT , QueryError > ;
1038
+ type Item = Result < RowT , NextRowError > ;
1039
1039
1040
1040
fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
1041
1041
let next_fut = async {
1042
1042
self . raw_row_lending_stream . next ( ) . await . map ( |res| {
1043
1043
res. and_then ( |column_iterator| {
1044
1044
<RowT as DeserializeRow >:: deserialize ( column_iterator)
1045
- . map_err ( |err| NextRowError :: RowDeserializationError ( err ) . into ( ) )
1045
+ . map_err ( NextRowError :: RowDeserializationError )
1046
1046
} )
1047
1047
} )
1048
1048
} ;
@@ -1057,12 +1057,17 @@ where
1057
1057
#[ derive( Error , Debug , Clone ) ]
1058
1058
#[ non_exhaustive]
1059
1059
pub enum NextPageError {
1060
+ /// PK extraction and/or token calculation error. Applies only for prepared statements.
1061
+ #[ error( "Failed to extract PK and compute token required for routing: {0}" ) ]
1062
+ PartitionKeyError ( #[ from] PartitionKeyError ) ,
1063
+
1064
+ /// Failed to run a request responsible for fetching new page.
1065
+ #[ error( transparent) ]
1066
+ RequestFailure ( #[ from] RequestError ) ,
1067
+
1060
1068
/// Failed to deserialize result metadata associated with next page response.
1061
1069
#[ error( "Failed to deserialize result metadata associated with next page response: {0}" ) ]
1062
1070
ResultMetadataParseError ( #[ from] ResultMetadataAndRowsCountParseError ) ,
1063
- // TODO: This should also include a variant representing an error that occurred during
1064
- // query that fetches the next page. However, as of now, it would require that we include QueryError here.
1065
- // This would introduce a cyclic dependency: QueryError -> NextRowError -> NextPageError -> QueryError.
1066
1071
}
1067
1072
1068
1073
/// An error returned by async iterator API.
@@ -1172,7 +1177,7 @@ mod legacy {
1172
1177
pub enum LegacyNextRowError {
1173
1178
/// Query to fetch next page has failed
1174
1179
#[ error( transparent) ]
1175
- QueryError ( #[ from] QueryError ) ,
1180
+ NextRowError ( #[ from] NextRowError ) ,
1176
1181
1177
1182
/// Parsing values in row as given types failed
1178
1183
#[ error( transparent) ]
0 commit comments