@@ -12,8 +12,9 @@ use super::pb;
12
12
13
13
pub use error_details:: { vec:: ErrorDetail , ErrorDetails } ;
14
14
pub use std_messages:: {
15
- BadRequest , DebugInfo , ErrorInfo , FieldViolation , Help , HelpLink , PreconditionFailure ,
16
- PreconditionViolation , QuotaFailure , QuotaViolation , RequestInfo , ResourceInfo , RetryInfo ,
15
+ BadRequest , DebugInfo , ErrorInfo , FieldViolation , Help , HelpLink , LocalizedMessage ,
16
+ PreconditionFailure , PreconditionViolation , QuotaFailure , QuotaViolation , RequestInfo ,
17
+ ResourceInfo , RetryInfo ,
17
18
} ;
18
19
19
20
trait IntoAny {
@@ -446,6 +447,28 @@ pub trait StatusExt: crate::sealed::Sealed {
446
447
/// }
447
448
/// ```
448
449
fn get_details_help ( & self ) -> Option < Help > ;
450
+
451
+ /// Get first [`LocalizedMessage`] details found on `tonic::Status`, if
452
+ /// any. If some `prost::DecodeError` occurs, returns `None`.
453
+ ///
454
+ /// # Examples
455
+ ///
456
+ /// ```
457
+ /// use tonic::{Status, Response};
458
+ /// use tonic_types::StatusExt;
459
+ ///
460
+ /// fn handle_request_result<T>(req_result: Result<Response<T>, Status>) {
461
+ /// match req_result {
462
+ /// Ok(_) => {},
463
+ /// Err(status) => {
464
+ /// if let Some(localized_message) = status.get_details_localized_message() {
465
+ /// // Handle localized_message details
466
+ /// }
467
+ /// }
468
+ /// };
469
+ /// }
470
+ /// ```
471
+ fn get_details_localized_message ( & self ) -> Option < LocalizedMessage > ;
449
472
}
450
473
451
474
impl crate :: sealed:: Sealed for tonic:: Status { }
@@ -497,6 +520,10 @@ impl StatusExt for tonic::Status {
497
520
conv_details. push ( help. into_any ( ) ) ;
498
521
}
499
522
523
+ if let Some ( localized_message) = details. localized_message {
524
+ conv_details. push ( localized_message. into_any ( ) ) ;
525
+ }
526
+
500
527
let details = gen_details_bytes ( code, & message, conv_details) ;
501
528
502
529
tonic:: Status :: with_details_and_metadata ( code, message, details, metadata)
@@ -545,6 +572,9 @@ impl StatusExt for tonic::Status {
545
572
ErrorDetail :: Help ( help) => {
546
573
conv_details. push ( help. into_any ( ) ) ;
547
574
}
575
+ ErrorDetail :: LocalizedMessage ( loc_message) => {
576
+ conv_details. push ( loc_message. into_any ( ) ) ;
577
+ }
548
578
}
549
579
}
550
580
@@ -600,6 +630,9 @@ impl StatusExt for tonic::Status {
600
630
Help :: TYPE_URL => {
601
631
details. help = Some ( Help :: from_any ( any) ?) ;
602
632
}
633
+ LocalizedMessage :: TYPE_URL => {
634
+ details. localized_message = Some ( LocalizedMessage :: from_any ( any) ?) ;
635
+ }
603
636
_ => { }
604
637
}
605
638
}
@@ -645,6 +678,9 @@ impl StatusExt for tonic::Status {
645
678
Help :: TYPE_URL => {
646
679
details. push ( Help :: from_any ( any) ?. into ( ) ) ;
647
680
}
681
+ LocalizedMessage :: TYPE_URL => {
682
+ details. push ( LocalizedMessage :: from_any ( any) ?. into ( ) ) ;
683
+ }
648
684
_ => { }
649
685
}
650
686
}
@@ -781,6 +817,20 @@ impl StatusExt for tonic::Status {
781
817
782
818
None
783
819
}
820
+
821
+ fn get_details_localized_message ( & self ) -> Option < LocalizedMessage > {
822
+ let status = pb:: Status :: decode ( self . details ( ) ) . ok ( ) ?;
823
+
824
+ for any in status. details . into_iter ( ) {
825
+ if any. type_url . as_str ( ) == LocalizedMessage :: TYPE_URL {
826
+ if let Ok ( detail) = LocalizedMessage :: from_any ( any) {
827
+ return Some ( detail) ;
828
+ }
829
+ }
830
+ }
831
+
832
+ None
833
+ }
784
834
}
785
835
786
836
#[ cfg( test) ]
@@ -789,8 +839,8 @@ mod tests {
789
839
use tonic:: { Code , Status } ;
790
840
791
841
use super :: {
792
- BadRequest , DebugInfo , ErrorDetails , ErrorInfo , Help , PreconditionFailure , QuotaFailure ,
793
- RequestInfo , ResourceInfo , RetryInfo , StatusExt ,
842
+ BadRequest , DebugInfo , ErrorDetails , ErrorInfo , Help , LocalizedMessage ,
843
+ PreconditionFailure , QuotaFailure , RequestInfo , ResourceInfo , RetryInfo , StatusExt ,
794
844
} ;
795
845
796
846
#[ test]
@@ -812,7 +862,8 @@ mod tests {
812
862
. add_bad_request_violation ( "field" , "description" )
813
863
. set_request_info ( "request-id" , "some-request-data" )
814
864
. set_resource_info ( "resource-type" , "resource-name" , "owner" , "description" )
815
- . add_help_link ( "link to resource" , "resource.example.local" ) ;
865
+ . add_help_link ( "link to resource" , "resource.example.local" )
866
+ . set_localized_message ( "en-US" , "message for the user" ) ;
816
867
817
868
let fmt_details = format ! ( "{:?}" , err_details) ;
818
869
@@ -830,6 +881,7 @@ mod tests {
830
881
RequestInfo :: new( "request-id" , "some-request-data" ) . into( ) ,
831
882
ResourceInfo :: new( "resource-type" , "resource-name" , "owner" , "description" ) . into( ) ,
832
883
Help :: with_link( "link to resource" , "resource.example.local" ) . into( ) ,
884
+ LocalizedMessage :: new( "en-US" , "message for the user" ) . into( ) ,
833
885
] ;
834
886
835
887
let fmt_details_vec = format ! ( "{:?}" , err_details_vec) ;
0 commit comments