Git repository hosting, collaboration, and discovery for the Fediverse.
Error handling fixes
parent: tbd commit: 5eaea71
Showing 4 changed files with 48 insertions and 99 deletions
src/daemon_backend.rs
@@ -1,9 +1,10 @@ | ||
1 | use std::{fmt::Debug, sync::Arc}; | |
1 | use std::{fmt::Debug, str::FromStr, sync::Arc}; | |
2 | 2 | |
3 | 3 | use futures_util::{SinkExt, StreamExt}; |
4 | 4 | use giterated_models::{ |
5 | 5 | authenticated::{Authenticated, AuthenticationSourceProviders}, |
6 | 6 | error::OperationError, |
7 | error::{IntoInternalError, NetworkOperationError}, | |
7 | 8 | message::GiteratedMessage, |
8 | 9 | object::{GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse}, |
9 | 10 | object_backend::ObjectBackend, |
@@ -49,11 +50,9 @@ impl ObjectBackend<NetworkOperationState> for DaemonConnectionPool { | ||
49 | 50 | payload, |
50 | 51 | }; |
51 | 52 | |
52 | let mut connection = self | |
53 | .0 | |
54 | .get() | |
55 | .await | |
56 | .map_err(|e| OperationError::Internal(e.to_string()))?; | |
53 | let mut connection = self.0.get().await.map_err(|e| { | |
54 | OperationError::Internal(anyhow::Error::from(ConnectionFailed(e.to_string()))) | |
55 | })?; | |
57 | 56 | |
58 | 57 | let mut authenticated = Authenticated::new(message); |
59 | 58 | for authentication in &operation_state.authentication { |
@@ -76,11 +75,9 @@ impl ObjectBackend<NetworkOperationState> for DaemonConnectionPool { | ||
76 | 75 | payload: operation, |
77 | 76 | }; |
78 | 77 | |
79 | let mut connection = self | |
80 | .0 | |
81 | .get() | |
82 | .await | |
83 | .map_err(|e| OperationError::Internal(e.to_string()))?; | |
78 | let mut connection = self.0.get().await.map_err(|e| { | |
79 | OperationError::Internal(anyhow::Error::from(ConnectionFailed(e.to_string()))) | |
80 | })?; | |
84 | 81 | |
85 | 82 | let mut authenticated = Authenticated::new(message); |
86 | 83 | for authentication in &operation_state.authentication { |
@@ -88,13 +85,12 @@ impl ObjectBackend<NetworkOperationState> for DaemonConnectionPool { | ||
88 | 85 | } |
89 | 86 | |
90 | 87 | let object_raw: ObjectResponse = send_expect(&mut connection, authenticated).await?; |
91 | Ok(unsafe { | |
92 | Object::new_unchecked( | |
93 | O::from_str(&object_raw.0) | |
94 | .map_err(|_e| OperationError::Internal("heck".to_string()))?, | |
95 | self.clone(), | |
96 | ) | |
97 | }) | |
88 | ||
89 | if let Ok(object) = O::from_str(&object_raw.0) { | |
90 | Ok(unsafe { Object::new_unchecked(object, self.clone()) }) | |
91 | } else { | |
92 | panic!() | |
93 | } | |
98 | 94 | } |
99 | 95 | } |
100 | 96 | |
@@ -112,30 +108,33 @@ async fn send_expect< | ||
112 | 108 | socket |
113 | 109 | .send(Message::Binary(payload)) |
114 | 110 | .await |
115 | .map_err(|e| OperationError::Internal(e.to_string()))?; | |
111 | .as_internal_error()?; | |
116 | 112 | |
117 | 113 | while let Some(message) = socket.next().await { |
118 | let payload = match message.map_err(|e| OperationError::Internal(e.to_string()))? { | |
114 | let payload = match message.as_internal_error()? { | |
119 | 115 | Message::Binary(payload) => payload, |
120 | 116 | _ => { |
121 | 117 | continue; |
122 | 118 | } |
123 | 119 | }; |
124 | 120 | |
125 | let raw_result = bincode::deserialize::<Result<Vec<u8>, OperationError<Vec<u8>>>>(&payload) | |
126 | .map_err(|e| OperationError::Internal(e.to_string()))?; | |
121 | let raw_result = | |
122 | bincode::deserialize::<Result<Vec<u8>, NetworkOperationError<Vec<u8>>>>(&payload) | |
123 | .map_err(|e| OperationError::Internal(anyhow::Error::from(e)))?; | |
127 | 124 | |
128 | 125 | // Map ok |
129 | 126 | let raw_result = match raw_result { |
130 | 127 | Ok(raw) => Ok(serde_json::from_slice(&raw) |
131 | .map_err(|e| OperationError::Internal(e.to_string()))?), | |
128 | .map_err(|e| OperationError::Internal(anyhow::Error::from(e)))?), | |
132 | 129 | Err(err) => Err(match err { |
133 | OperationError::Operation(err) => OperationError::Operation( | |
130 | NetworkOperationError::Operation(err) => OperationError::Operation( | |
134 | 131 | serde_json::from_slice(&err) |
135 | .map_err(|e| OperationError::Internal(e.to_string()))?, | |
132 | .map_err(|e| OperationError::Internal(anyhow::Error::from(e)))?, | |
136 | 133 | ), |
137 | OperationError::Internal(err) => OperationError::Internal(err), | |
138 | OperationError::Unhandled => OperationError::Unhandled, | |
134 | NetworkOperationError::Internal => { | |
135 | OperationError::Internal(anyhow::Error::from(NetworkError)) | |
136 | } | |
137 | NetworkOperationError::Unhandled => OperationError::Unhandled, | |
139 | 138 | }), |
140 | 139 | }; |
141 | 140 | |
@@ -144,3 +143,11 @@ async fn send_expect< | ||
144 | 143 | |
145 | 144 | panic!() |
146 | 145 | } |
146 | ||
147 | #[derive(Debug, thiserror::Error)] | |
148 | #[error("a remote internal error occurred")] | |
149 | pub struct NetworkError; | |
150 | ||
151 | #[derive(Debug, thiserror::Error)] | |
152 | #[error("failed to get connection from pool: {0}")] | |
153 | pub struct ConnectionFailed(String); |
src/lib.rs
@@ -27,9 +27,7 @@ impl Debug for DaemonConnectionPool { | ||
27 | 27 | } |
28 | 28 | |
29 | 29 | impl DaemonConnectionPool { |
30 | pub fn connect( | |
31 | instance: impl ToOwned<Owned = Instance>, | |
32 | ) -> Result<Self, BuildError> { | |
30 | pub fn connect(instance: impl ToOwned<Owned = Instance>) -> Result<Self, BuildError> { | |
33 | 31 | let instance = instance.to_owned(); |
34 | 32 | Ok(Self( |
35 | 33 | Pool::builder(GiteratedConnectionPool { |
src/main.rs
@@ -5,9 +5,9 @@ use giterated_models::{ | ||
5 | 5 | authenticated::{InstanceAuthenticator, UserAuthenticator}, |
6 | 6 | instance::Instance, |
7 | 7 | object_backend::ObjectBackend, |
8 | repository::{AccessList, Repository}, | |
8 | repository::{AccessList, Description, Repository}, | |
9 | 9 | settings::AnySetting, |
10 | user::{DisplayName, User}, | |
10 | user::{Bio, DisplayName, User}, | |
11 | 11 | }; |
12 | 12 | |
13 | 13 | use color_eyre::eyre::Result; |
@@ -29,88 +29,32 @@ async fn main() -> Result<()> { | ||
29 | 29 | let mut operation_state = NetworkOperationState::new(); |
30 | 30 | |
31 | 31 | let mut user = pool |
32 | .get_object::<User>("ambee:giterated.dev", &operation_state) | |
32 | .get_object::<User>("test:giterated.dev", &operation_state) | |
33 | 33 | .await?; |
34 | 34 | |
35 | // info!("Getting display name for {}!", user); | |
35 | let bio = user.get::<Bio>(&operation_state).await?; | |
36 | 36 | |
37 | let display_name = user.get::<DisplayName>(&operation_state).await?; | |
38 | ||
39 | // info!("{}'s display name is {}", user, display_name); | |
37 | info!("Bio: {}", bio); | |
40 | 38 | |
41 | 39 | let repositories = user |
42 | .repositories( | |
43 | &Instance::from_str("giterated.dev").unwrap(), | |
44 | &operation_state, | |
45 | ) | |
40 | .repositories(&Instance::from_str("giterated.dev")?, &operation_state) | |
46 | 41 | .await?; |
47 | 42 | |
48 | // info!("Repository: {:#?}", repositories); | |
43 | let repository = repositories.first().unwrap(); | |
49 | 44 | |
50 | 45 | let mut repository = pool |
51 | .get_object::<Repository>( | |
52 | &repositories.first().unwrap().repository.to_string(), | |
53 | &operation_state, | |
54 | ) | |
46 | .get_object::<Repository>(&repository.repository.to_string(), &operation_state) | |
55 | 47 | .await?; |
56 | 48 | |
57 | // info!("First repository: {}", repository.object().to_string()); | |
58 | ||
59 | // info!("First repository description: {}", repository.get::<Description>().await?); | |
60 | // info!("First repository visibility: {:?}", repository.get::<Visibility>().await?); | |
61 | // info!("First repository default branch: {}", repository.get::<DefaultBranch>().await?); | |
62 | ||
63 | 49 | info!( |
64 | "First repository info: {:#?}", | |
65 | repository.info(false, None, None, &operation_state).await? | |
50 | "Repository description: {}", | |
51 | repository.get::<Description>(&operation_state).await? | |
66 | 52 | ); |
67 | 53 | |
68 | let cold_duration = start.elapsed(); | |
69 | let warm_start = Instant::now(); | |
70 | ||
71 | let mut operation_state = NetworkOperationState::new(); | |
72 | ||
73 | let mut user = pool | |
74 | .get_object::<User>("ambee:giterated.dev", &operation_state) | |
75 | .await?; | |
76 | ||
77 | // info!("Getting display name for {}!", user); | |
78 | ||
79 | let display_name = user.get::<DisplayName>(&operation_state).await?; | |
80 | ||
81 | // info!("{}'s display name is {}", user, display_name); | |
82 | ||
83 | let repositories = user | |
84 | .repositories( | |
85 | &Instance::from_str("giterated.dev").unwrap(), | |
86 | &operation_state, | |
87 | ) | |
88 | .await?; | |
89 | ||
90 | // info!("Repository: {:#?}", repositories); | |
91 | ||
92 | let mut repository = pool | |
93 | .get_object::<Repository>( | |
94 | &repositories.first().unwrap().repository.to_string(), | |
95 | &operation_state, | |
96 | ) | |
97 | .await?; | |
98 | ||
99 | // info!("First repository: {}", repository.object().to_string()); | |
100 | ||
101 | // info!("First repository description: {}", repository.get::<Description>().await?); | |
102 | // info!("First repository visibility: {:?}", repository.get::<Visibility>().await?); | |
103 | // info!("First repository default branch: {}", repository.get::<DefaultBranch>().await?); | |
104 | ||
105 | 54 | info!( |
106 | "First repository info: {:#?}", | |
107 | repository.info(false, None, None, &operation_state).await? | |
55 | "User Bio Setting: {}", | |
56 | user.get_setting::<Bio>(&operation_state).await? | |
108 | 57 | ); |
109 | 58 | |
110 | let warm_duration = warm_start.elapsed(); | |
111 | ||
112 | info!("Cold request time: {}ms", cold_duration.as_millis()); | |
113 | info!("Warm request time: {}ms", warm_duration.as_millis()); | |
114 | ||
115 | 59 | Ok(()) |
116 | 60 | } |
src/pool.rs
@@ -1,6 +1,6 @@ | ||
1 | 1 | use std::net::SocketAddr; |
2 | 2 | |
3 | use deadpool::managed::{Manager, RecycleError, RecycleResult, Metrics}; | |
3 | use deadpool::managed::{Manager, Metrics, RecycleError, RecycleResult}; | |
4 | 4 | use futures_util::SinkExt; |
5 | 5 | use giterated_models::instance::Instance; |
6 | 6 | use tokio_tungstenite::{connect_async, tungstenite::Message}; |