A better Rust ATProto crate
103
fork

Configure Feed

Select the types of activity you want to include in your feed.

interim more resilient error parsing for auth errors

Orual bfb72e29 2c6880ce

+49 -11
+49 -11
crates/jacquard-common/src/xrpc.rs
··· 48 48 }; 49 49 use serde::{Deserialize, Serialize}; 50 50 use smol_str::SmolStr; 51 + 51 52 #[cfg(feature = "websocket")] 52 53 pub use subscription::{ 53 54 BasicSubscriptionClient, MessageEncoding, SubscriptionCall, SubscriptionClient, ··· 485 486 Resp: XrpcResp, 486 487 { 487 488 let status = http_response.status(); 489 + 488 490 // If the server returned 401 with a WWW-Authenticate header, expose it so higher layers 489 491 // (e.g., DPoP handling) can detect `error="invalid_token"` and trigger refresh. 490 492 #[allow(deprecated)] 491 493 if status.as_u16() == 401 { 492 494 if let Some(hv) = http_response.headers().get(http::header::WWW_AUTHENTICATE) { 493 - return Err(crate::error::ClientError::auth( 494 - crate::error::AuthError::Other(hv.clone()), 495 - ) 496 - .for_nsid(Resp::NSID)); 495 + return Err( 496 + crate::error::ClientError::auth(crate::error::AuthError::Other(hv.clone())) 497 + .for_nsid(Resp::NSID), 498 + ); 497 499 } 498 500 } 499 501 let buffer = Bytes::from(http_response.into_body()); ··· 670 672 } 671 673 // 400: try typed XRPC error, fallback to generic error 672 674 } else if self.status.as_u16() == 400 { 673 - match serde_json::from_slice::<_>(&self.buffer) { 674 - Ok(error) => Err(XrpcError::Xrpc(error)), 675 + match serde_json::from_slice::<R::Err<'_>>(&self.buffer) { 676 + Ok(error) => { 677 + use alloc::string::ToString; 678 + if error.to_string().contains("InvalidToken") { 679 + Err(XrpcError::Auth(AuthError::InvalidToken)) 680 + } else if error.to_string().contains("ExpiredToken") { 681 + Err(XrpcError::Auth(AuthError::TokenExpired)) 682 + } else { 683 + Err(XrpcError::Xrpc(error)) 684 + } 685 + } 675 686 Err(_) => { 676 687 // Fallback to generic error (InvalidRequest, ExpiredToken, etc.) 677 688 match serde_json::from_slice::<GenericXrpcError>(&self.buffer) { ··· 730 741 } 731 742 // 400: try typed XRPC error, fallback to generic error 732 743 } else if self.status.as_u16() == 400 { 733 - match serde_json::from_slice::<_>(&self.buffer) { 734 - Ok(error) => Err(XrpcError::Xrpc(error)), 744 + match serde_json::from_slice::<R::Err<'_>>(&self.buffer) { 745 + Ok(error) => { 746 + use alloc::string::ToString; 747 + if error.to_string().contains("InvalidToken") { 748 + Err(XrpcError::Auth(AuthError::InvalidToken)) 749 + } else if error.to_string().contains("ExpiredToken") { 750 + Err(XrpcError::Auth(AuthError::TokenExpired)) 751 + } else { 752 + Err(XrpcError::Xrpc(error)) 753 + } 754 + } 735 755 Err(_) => { 736 756 // Fallback to generic error (InvalidRequest, ExpiredToken, etc.) 737 757 match serde_json::from_slice::<GenericXrpcError>(&self.buffer) { ··· 790 810 } 791 811 // 400: try typed XRPC error, fallback to generic error 792 812 } else if self.status.as_u16() == 400 { 793 - match serde_json::from_slice::<_>(&self.buffer) { 794 - Ok(error) => Err(XrpcError::Xrpc(error)), 813 + match serde_json::from_slice::<R::Err<'_>>(&self.buffer) { 814 + Ok(error) => { 815 + use alloc::string::ToString; 816 + if error.to_string().contains("InvalidToken") { 817 + Err(XrpcError::Auth(AuthError::InvalidToken)) 818 + } else if error.to_string().contains("ExpiredToken") { 819 + Err(XrpcError::Auth(AuthError::TokenExpired)) 820 + } else { 821 + Err(XrpcError::Xrpc(error)) 822 + } 823 + } 795 824 Err(_) => { 796 825 // Fallback to generic error (InvalidRequest, ExpiredToken, etc.) 797 826 match serde_json::from_slice::<GenericXrpcError>(&self.buffer) { ··· 876 905 // 400: try typed XRPC error, fallback to generic error 877 906 } else if self.status.as_u16() == 400 { 878 907 let error = match parse_error::<R>(&self.buffer) { 879 - Ok(error) => XrpcError::Xrpc(error), 908 + Ok(error) => { 909 + use alloc::string::ToString; 910 + if error.to_string().contains("InvalidToken") { 911 + XrpcError::Auth(AuthError::InvalidToken) 912 + } else if error.to_string().contains("ExpiredToken") { 913 + XrpcError::Auth(AuthError::TokenExpired) 914 + } else { 915 + XrpcError::Xrpc(error) 916 + } 917 + } 880 918 Err(_) => { 881 919 // Fallback to generic error (InvalidRequest, ExpiredToken, etc.) 882 920 match serde_json::from_slice::<GenericXrpcError>(&self.buffer) {