1 file changed
+60
-17
crates/smbcloud-network/src/network.rs
+60
-17
@@ -160,9 +160,8 @@ pub async fn request_login(builder: RequestBuilder) -> Result<AccountStatus, Err
160
Ok(AccountStatus::NotFound)
161
}
162
(StatusCode::UNPROCESSABLE_ENTITY, _) => {
163
- // Account found but email not verified / password not set.
164
- let result: SmbAuthorization = match response.json().await {
165
- Ok(res) => res,
163
+ let body_text = match response.text().await {
164
+ Ok(text) => text,
165
Err(_) => {
166
return Err(ErrorResponse::Error {
167
error_code: ErrorCode::NetworkError,
@@ -170,21 +169,42 @@ pub async fn request_login(builder: RequestBuilder) -> Result<AccountStatus, Err
169
});
170
}
171
};
173
- // println!("Result: {:#?}", &result);
172
+
173
+ let result: SmbAuthorization = match serde_json::from_str(&body_text) {
174
+ Ok(res) => res,
175
+ Err(_) => {
176
+ // Try generic JSON for a useful message.
177
+ let message = serde_json::from_str::<serde_json::Value>(&body_text)
178
+ .ok()
179
+ .and_then(|v| {
180
+ v.get("message")
181
+ .and_then(serde_json::Value::as_str)
182
+ .map(ToOwned::to_owned)
183
+ })
184
+ .unwrap_or_else(|| ErrorCode::NetworkError.message(None).to_string());
185
+ return Err(ErrorResponse::Error {
186
+ error_code: ErrorCode::NetworkError,
187
+ message,
188
+ });
189
+ }
190
+ };
191
+
192
let error_code = match result.error_code {
193
Some(code) => code,
194
None => {
195
+ // No error_code but we have a message — return it as Incomplete with a
196
+ // generic unverified status so the client can display the message.
197
return Err(ErrorResponse::Error {
198
error_code: ErrorCode::NetworkError,
179
- message: ErrorCode::NetworkError.message(None).to_string(),
199
+ message: result.message,
200
});
201
}
202
};
203
Ok(AccountStatus::Incomplete { status: error_code })
204
}
205
(StatusCode::UNAUTHORIZED, _) => {
186
- let result: SmbAuthorization = match response.json().await {
187
- Ok(res) => res,
206
+ let body_text = match response.text().await {
207
+ Ok(text) => text,
208
Err(_) => {
209
return Err(ErrorResponse::Error {
210
error_code: ErrorCode::NetworkError,
@@ -192,18 +212,41 @@ pub async fn request_login(builder: RequestBuilder) -> Result<AccountStatus, Err
212
});
213
}
214
};
195
- let error_code = match result.error_code {
196
- Some(code) => code,
197
- None => {
198
- return Err(ErrorResponse::Error {
199
- error_code: ErrorCode::NetworkError,
200
- message: ErrorCode::NetworkError.message(None).to_string(),
201
- });
202
- }
203
- };
215
+
216
+ // Try parsing as SmbAuthorization first.
217
+ if let Ok(result) = serde_json::from_str::<SmbAuthorization>(&body_text) {
218
+ let error_code = match result.error_code {
219
+ Some(code) => code,
220
+ None => {
221
+ // Response parsed but no error_code — surface the server's message.
222
+ return Err(ErrorResponse::Error {
223
+ error_code: ErrorCode::Unauthorized,
224
+ message: result.message,
225
+ });
226
+ }
227
+ };
228
+ return Err(ErrorResponse::Error {
229
+ error_code: ErrorCode::Unauthorized,
230
+ message: error_code.to_string(),
231
+ });
232
+ }
233
+
234
+ // Fallback: try to extract message or error from a generic JSON object.
235
+ if let Ok(generic) = serde_json::from_str::<serde_json::Value>(&body_text) {
236
+ let extracted = generic
237
+ .get("message")
238
+ .or_else(|| generic.get("error"))
239
+ .and_then(serde_json::Value::as_str)
240
+ .unwrap_or("Sign in failed.");
241
+ return Err(ErrorResponse::Error {
242
+ error_code: ErrorCode::Unauthorized,
243
+ message: extracted.to_string(),
244
+ });
245
+ }
246
+
247
Err(ErrorResponse::Error {
248
error_code: ErrorCode::Unauthorized,
206
- message: error_code.to_string(),
249
+ message: "Sign in failed.".to_string(),
250
})
251
}
252
(status, _) => parse_error_response(response)