@@ -37,6 +37,7 @@ use crate::observability::history::{self, HistoryListener};
37
37
use crate :: observability:: metrics:: Metrics ;
38
38
use crate :: policies:: load_balancing:: { self , RoutingInfo } ;
39
39
use crate :: policies:: retry:: { RequestInfo , RetryDecision , RetrySession } ;
40
+ use crate :: prepared_statement:: PartitionKeyError ;
40
41
use crate :: response:: query_result:: ColumnSpecs ;
41
42
use crate :: response:: { NonErrorQueryResponse , QueryResponse } ;
42
43
use crate :: statement:: { prepared_statement:: PreparedStatement , query:: Query } ;
@@ -78,9 +79,7 @@ mod checked_channel_sender {
78
79
use tokio:: sync:: mpsc;
79
80
use uuid:: Uuid ;
80
81
81
- use crate :: errors:: QueryError ;
82
-
83
- use super :: ReceivedPage ;
82
+ use super :: { NextPageError , ReceivedPage } ;
84
83
85
84
/// A value whose existence proves that there was an attempt
86
85
/// to send an item of type T through a channel.
@@ -105,7 +104,7 @@ mod checked_channel_sender {
105
104
}
106
105
}
107
106
108
- type ResultPage = Result < ReceivedPage , QueryError > ;
107
+ type ResultPage = Result < ReceivedPage , NextPageError > ;
109
108
110
109
impl ProvingSender < ResultPage > {
111
110
pub ( crate ) async fn send_empty_page (
@@ -126,12 +125,12 @@ mod checked_channel_sender {
126
125
127
126
use checked_channel_sender:: { ProvingSender , SendAttemptedProof } ;
128
127
129
- type PageSendAttemptedProof = SendAttemptedProof < Result < ReceivedPage , QueryError > > ;
128
+ type PageSendAttemptedProof = SendAttemptedProof < Result < ReceivedPage , NextPageError > > ;
130
129
131
130
// PagerWorker works in the background to fetch pages
132
131
// QueryPager receives them through a channel
133
132
struct PagerWorker < ' a , QueryFunc , SpanCreatorFunc > {
134
- sender : ProvingSender < Result < ReceivedPage , QueryError > > ,
133
+ sender : ProvingSender < Result < ReceivedPage , NextPageError > > ,
135
134
136
135
// Closure used to perform a single page query
137
136
// AsyncFn(Arc<Connection>, Option<Arc<[u8]>>) -> Result<QueryResponse, RequestAttemptError>
@@ -266,7 +265,10 @@ where
266
265
}
267
266
268
267
self . log_request_error ( & last_error) ;
269
- 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 ;
270
272
proof
271
273
}
272
274
@@ -476,7 +478,7 @@ where
476
478
/// any complicated logic related to retries, it just fetches pages from
477
479
/// a single connection.
478
480
struct SingleConnectionPagerWorker < Fetcher > {
479
- sender : ProvingSender < Result < ReceivedPage , QueryError > > ,
481
+ sender : ProvingSender < Result < ReceivedPage , NextPageError > > ,
480
482
fetcher : Fetcher ,
481
483
}
482
484
@@ -489,7 +491,12 @@ where
489
491
match self . do_work ( ) . await {
490
492
Ok ( proof) => proof,
491
493
Err ( err) => {
492
- let ( proof, _) = self . sender . send ( Err ( err. into_query_error ( ) ) ) . await ;
494
+ let ( proof, _) = self
495
+ . sender
496
+ . send ( Err ( NextPageError :: RequestFailure (
497
+ RequestError :: LastAttemptError ( err) ,
498
+ ) ) )
499
+ . await ;
493
500
proof
494
501
}
495
502
}
@@ -559,7 +566,7 @@ where
559
566
/// is not the intended target type.
560
567
pub struct QueryPager {
561
568
current_page : RawRowLendingIterator ,
562
- page_receiver : mpsc:: Receiver < Result < ReceivedPage , QueryError > > ,
569
+ page_receiver : mpsc:: Receiver < Result < ReceivedPage , NextPageError > > ,
563
570
tracing_ids : Vec < Uuid > ,
564
571
}
565
572
@@ -581,7 +588,7 @@ impl QueryPager {
581
588
let res = std:: future:: poll_fn ( |cx| Pin :: new ( & mut * self ) . poll_fill_page ( cx) ) . await ;
582
589
match res {
583
590
Some ( Ok ( ( ) ) ) => { }
584
- Some ( Err ( err) ) => return Some ( Err ( err) ) ,
591
+ Some ( Err ( err) ) => return Some ( Err ( err. into ( ) ) ) ,
585
592
None => return None ,
586
593
}
587
594
@@ -598,7 +605,7 @@ impl QueryPager {
598
605
fn poll_fill_page < ' r > (
599
606
mut self : Pin < & ' r mut Self > ,
600
607
cx : & mut Context < ' _ > ,
601
- ) -> Poll < Option < Result < ( ) , QueryError > > > {
608
+ ) -> Poll < Option < Result < ( ) , NextRowError > > > {
602
609
if !self . is_current_page_exhausted ( ) {
603
610
return Poll :: Ready ( Some ( Ok ( ( ) ) ) ) ;
604
611
}
@@ -621,14 +628,11 @@ impl QueryPager {
621
628
fn poll_next_page < ' r > (
622
629
mut self : Pin < & ' r mut Self > ,
623
630
cx : & mut Context < ' _ > ,
624
- ) -> Poll < Option < Result < ( ) , QueryError > > > {
631
+ ) -> Poll < Option < Result < ( ) , NextRowError > > > {
625
632
let mut s = self . as_mut ( ) ;
626
633
627
634
let received_page = ready_some_ok ! ( Pin :: new( & mut s. page_receiver) . poll_recv( cx) ) ;
628
635
629
- // TODO: see my other comment next to QueryError::NextRowError
630
- // This is the place where conversion happens. To fix this, we need to refactor error types in iterator API.
631
- // The `page_receiver`'s error type should be narrowed from QueryError to some other error type.
632
636
let raw_rows_with_deserialized_metadata =
633
637
received_page. rows . deserialize_metadata ( ) . map_err ( |err| {
634
638
NextRowError :: NextPageError ( NextPageError :: ResultMetadataParseError ( err) )
@@ -683,8 +687,8 @@ impl QueryPager {
683
687
execution_profile : Arc < ExecutionProfileInner > ,
684
688
cluster_data : Arc < ClusterState > ,
685
689
metrics : Arc < Metrics > ,
686
- ) -> Result < Self , QueryError > {
687
- let ( sender, receiver) = mpsc:: channel ( 1 ) ;
690
+ ) -> Result < Self , NextRowError > {
691
+ let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , NextPageError > > ( 1 ) ;
688
692
689
693
let consistency = query
690
694
. config
@@ -762,8 +766,8 @@ impl QueryPager {
762
766
763
767
pub ( crate ) async fn new_for_prepared_statement (
764
768
config : PreparedIteratorConfig ,
765
- ) -> Result < Self , QueryError > {
766
- let ( sender, receiver) = mpsc:: channel ( 1 ) ;
769
+ ) -> Result < Self , NextRowError > {
770
+ let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , NextPageError > > ( 1 ) ;
767
771
768
772
let consistency = config
769
773
. prepared
@@ -798,7 +802,7 @@ impl QueryPager {
798
802
Ok ( res) => res. unzip ( ) ,
799
803
Err ( err) => {
800
804
let ( proof, _res) = ProvingSender :: from ( sender)
801
- . send ( Err ( err . into_query_error ( ) ) )
805
+ . send ( Err ( NextPageError :: PartitionKeyError ( err ) ) )
802
806
. await ;
803
807
return proof;
804
808
}
@@ -885,8 +889,8 @@ impl QueryPager {
885
889
connection : Arc < Connection > ,
886
890
consistency : Consistency ,
887
891
serial_consistency : Option < SerialConsistency > ,
888
- ) -> Result < Self , QueryError > {
889
- let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , QueryError > > ( 1 ) ;
892
+ ) -> Result < Self , NextRowError > {
893
+ let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , NextPageError > > ( 1 ) ;
890
894
891
895
let page_size = query. get_validated_page_size ( ) ;
892
896
@@ -915,8 +919,8 @@ impl QueryPager {
915
919
connection : Arc < Connection > ,
916
920
consistency : Consistency ,
917
921
serial_consistency : Option < SerialConsistency > ,
918
- ) -> Result < Self , QueryError > {
919
- let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , QueryError > > ( 1 ) ;
922
+ ) -> Result < Self , NextRowError > {
923
+ let ( sender, receiver) = mpsc:: channel :: < Result < ReceivedPage , NextPageError > > ( 1 ) ;
920
924
921
925
let page_size = prepared. get_validated_page_size ( ) ;
922
926
@@ -942,8 +946,8 @@ impl QueryPager {
942
946
943
947
async fn new_from_worker_future (
944
948
worker_task : impl Future < Output = PageSendAttemptedProof > + Send + ' static ,
945
- mut receiver : mpsc:: Receiver < Result < ReceivedPage , QueryError > > ,
946
- ) -> Result < Self , QueryError > {
949
+ mut receiver : mpsc:: Receiver < Result < ReceivedPage , NextPageError > > ,
950
+ ) -> Result < Self , NextRowError > {
947
951
tokio:: task:: spawn ( worker_task) ;
948
952
949
953
// This unwrap is safe because:
@@ -1053,12 +1057,17 @@ where
1053
1057
#[ derive( Error , Debug , Clone ) ]
1054
1058
#[ non_exhaustive]
1055
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
+
1056
1068
/// Failed to deserialize result metadata associated with next page response.
1057
1069
#[ error( "Failed to deserialize result metadata associated with next page response: {0}" ) ]
1058
1070
ResultMetadataParseError ( #[ from] ResultMetadataAndRowsCountParseError ) ,
1059
- // TODO: This should also include a variant representing an error that occurred during
1060
- // query that fetches the next page. However, as of now, it would require that we include QueryError here.
1061
- // This would introduce a cyclic dependency: QueryError -> NextRowError -> NextPageError -> QueryError.
1062
1071
}
1063
1072
1064
1073
/// An error returned by async iterator API.
0 commit comments