1use crate::{
13 models::{EvmRpcResult, NetworkRpcResult, OpenZeppelinErrorCodes, RpcErrorCodes},
14 models::{JsonRpcError, JsonRpcId, JsonRpcResponse},
15 services::ProviderError,
16};
17use serde_json;
18
19pub fn create_error_response(
33 id: Option<JsonRpcId>,
34 code: i32,
35 message: &str,
36 description: &str,
37) -> JsonRpcResponse<NetworkRpcResult> {
38 JsonRpcResponse {
39 id,
40 jsonrpc: "2.0".to_string(),
41 result: None,
42 error: Some(JsonRpcError {
43 code,
44 message: message.to_string(),
45 description: description.to_string(),
46 }),
47 }
48}
49
50pub fn create_success_response(
62 id: Option<JsonRpcId>,
63 result: serde_json::Value,
64) -> JsonRpcResponse<NetworkRpcResult> {
65 JsonRpcResponse {
66 id,
67 jsonrpc: "2.0".to_string(),
68 result: Some(NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(result))),
69 error: None,
70 }
71}
72
73pub fn map_provider_error(error: &ProviderError) -> (i32, &'static str) {
100 match error {
101 ProviderError::InvalidAddress(_) => (RpcErrorCodes::INVALID_PARAMS, "Invalid params"),
102 ProviderError::NetworkConfiguration(_) => (
103 OpenZeppelinErrorCodes::NETWORK_CONFIGURATION,
104 "Network configuration error",
105 ),
106 ProviderError::Timeout => (OpenZeppelinErrorCodes::TIMEOUT, "Request timeout"),
107 ProviderError::RateLimited => (OpenZeppelinErrorCodes::RATE_LIMITED, "Rate limited"),
108 ProviderError::BadGateway => (OpenZeppelinErrorCodes::BAD_GATEWAY, "Bad gateway"),
109 ProviderError::RequestError { .. } => {
110 (OpenZeppelinErrorCodes::REQUEST_ERROR, "Request error")
111 }
112 ProviderError::Other(_) => (RpcErrorCodes::INTERNAL_ERROR, "Internal error"),
113 _ => (RpcErrorCodes::INTERNAL_ERROR, "Internal error"),
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120 use crate::models::{OpenZeppelinErrorCodes, RpcErrorCodes};
121 use crate::services::{provider::rpc_selector::RpcSelectorError, SolanaProviderError};
122 use serde_json::json;
123
124 #[test]
125 fn test_create_error_response_basic() {
126 let response = create_error_response(
127 Some(JsonRpcId::Number(123)),
128 -32602,
129 "Invalid params",
130 "The provided parameters are invalid",
131 );
132
133 assert_eq!(response.id, Some(JsonRpcId::Number(123)));
134 assert_eq!(response.jsonrpc, "2.0");
135 assert!(response.result.is_none());
136 assert!(response.error.is_some());
137
138 let error = response.error.unwrap();
139 assert_eq!(error.code, -32602);
140 assert!(!error.message.is_empty());
141 assert!(!error.description.is_empty());
142 }
143
144 #[test]
145 fn test_create_error_response_zero_id() {
146 let response = create_error_response(
147 Some(JsonRpcId::Number(0)),
148 -32603,
149 "Internal error",
150 "Something went wrong",
151 );
152
153 assert_eq!(response.id, Some(JsonRpcId::Number(0)));
154 assert_eq!(response.jsonrpc, "2.0");
155 assert!(response.result.is_none());
156 assert!(response.error.is_some());
157 }
158
159 #[test]
160 fn test_create_error_response_max_id() {
161 let response = create_error_response(
162 Some(JsonRpcId::Number(u64::MAX as i64)),
163 -32700,
164 "Parse error",
165 "JSON parsing failed",
166 );
167
168 assert_eq!(response.id, Some(JsonRpcId::Number(u64::MAX as i64)));
169 assert_eq!(response.jsonrpc, "2.0");
170 assert!(response.result.is_none());
171 assert!(response.error.is_some());
172 }
173
174 #[test]
175 fn test_create_error_response_empty_message() {
176 let response = create_error_response(
177 Some(JsonRpcId::Number(42)),
178 -32601,
179 "",
180 "Method not found error",
181 );
182
183 assert_eq!(response.id, Some(JsonRpcId::Number(42)));
184 let error = response.error.unwrap();
185 assert!(error.message.is_empty());
186 assert!(!error.description.is_empty());
187 }
188
189 #[test]
190 fn test_create_error_response_empty_description() {
191 let response =
192 create_error_response(Some(JsonRpcId::Number(99)), -32600, "Invalid Request", "");
193
194 assert_eq!(response.id, Some(JsonRpcId::Number(99)));
195 let error = response.error.unwrap();
196 assert!(!error.message.is_empty());
197 assert!(error.description.is_empty());
198 }
199
200 #[test]
201 fn test_create_error_response_preserves_input() {
202 let message = "Error with unicode: 🚨 ñáéíóú";
203 let description = "Description with symbols: @#$%^&*()";
204 let response =
205 create_error_response(Some(JsonRpcId::Number(500)), -33000, message, description);
206
207 let error = response.error.unwrap();
208 assert!(!error.message.is_empty());
209 assert!(!error.description.is_empty());
210 assert_eq!(error.code, -33000);
211 }
212
213 #[test]
214 fn test_create_error_response_long_strings() {
215 let long_message = "a".repeat(1000);
216 let long_description = "b".repeat(2000);
217 let response = create_error_response(
218 Some(JsonRpcId::Number(777)),
219 -33001,
220 &long_message,
221 &long_description,
222 );
223
224 let error = response.error.unwrap();
225 assert_eq!(error.message.len(), 1000);
226 assert_eq!(error.description.len(), 2000);
227 }
228
229 #[test]
230 fn test_create_error_response_custom_openzeppelin_codes() {
231 let test_cases = vec![
232 OpenZeppelinErrorCodes::TIMEOUT,
233 OpenZeppelinErrorCodes::RATE_LIMITED,
234 OpenZeppelinErrorCodes::BAD_GATEWAY,
235 OpenZeppelinErrorCodes::REQUEST_ERROR,
236 OpenZeppelinErrorCodes::NETWORK_CONFIGURATION,
237 ];
238
239 for code in test_cases {
240 let response = create_error_response(
241 Some(JsonRpcId::Number(1)),
242 code,
243 "Test message",
244 "Test description",
245 );
246 let error = response.error.unwrap();
247 assert_eq!(error.code, code);
248 assert!(!error.message.is_empty());
249 assert!(!error.description.is_empty());
250 }
251 }
252
253 #[test]
254 fn test_create_error_response_standard_json_rpc_codes() {
255 let test_cases = vec![
256 RpcErrorCodes::PARSE,
257 RpcErrorCodes::INVALID_REQUEST,
258 RpcErrorCodes::METHOD_NOT_FOUND,
259 RpcErrorCodes::INVALID_PARAMS,
260 RpcErrorCodes::INTERNAL_ERROR,
261 ];
262
263 for code in test_cases {
264 let response = create_error_response(
265 Some(JsonRpcId::Number(1)),
266 code,
267 "Test message",
268 "Test description",
269 );
270 let error = response.error.unwrap();
271 assert_eq!(error.code, code);
272 assert!(!error.message.is_empty());
273 assert!(!error.description.is_empty());
274 }
275 }
276
277 #[test]
278 fn test_create_success_response_basic() {
279 let result_data = json!({
280 "blockNumber": "0x1234",
281 "hash": "0xabcd"
282 });
283
284 let response = create_success_response(Some(JsonRpcId::Number(456)), result_data.clone());
285
286 assert_eq!(response.id, Some(JsonRpcId::Number(456)));
287 assert_eq!(response.jsonrpc, "2.0");
288 assert!(response.error.is_none());
289 assert!(response.result.is_some());
290
291 match response.result.unwrap() {
292 NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(value)) => {
293 assert_eq!(value, result_data);
294 }
295 _ => unreachable!("Expected EVM RawRpcResult"),
296 }
297 }
298
299 #[test]
300 fn test_create_success_response_zero_id() {
301 let result_data = json!(null);
302 let response = create_success_response(Some(JsonRpcId::Number(0)), result_data);
303
304 assert_eq!(response.id, Some(JsonRpcId::Number(0)));
305 assert_eq!(response.jsonrpc, "2.0");
306 assert!(response.error.is_none());
307 }
308
309 #[test]
310 fn test_create_success_response_max_id() {
311 let result_data = json!(42);
312 let response =
313 create_success_response(Some(JsonRpcId::Number(u64::MAX as i64)), result_data);
314
315 assert_eq!(response.id, Some(JsonRpcId::Number(u64::MAX as i64)));
316 assert_eq!(response.jsonrpc, "2.0");
317 assert!(response.error.is_none());
318 }
319
320 #[test]
321 fn test_create_success_response_null_result() {
322 let result_data = json!(null);
323 let response = create_success_response(Some(JsonRpcId::Number(100)), result_data.clone());
324
325 match response.result.unwrap() {
326 NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(value)) => {
327 assert_eq!(value, result_data);
328 assert!(value.is_null());
329 }
330 _ => unreachable!("Expected EVM RawRpcResult"),
331 }
332 }
333
334 #[test]
335 fn test_create_success_response_boolean_result() {
336 let result_data = json!(true);
337 let response = create_success_response(Some(JsonRpcId::Number(200)), result_data.clone());
338
339 match response.result.unwrap() {
340 NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(value)) => {
341 assert_eq!(value, result_data);
342 assert!(value.is_boolean());
343 }
344 _ => unreachable!("Expected EVM RawRpcResult"),
345 }
346 }
347
348 #[test]
349 fn test_create_success_response_number_result() {
350 let result_data = json!(12345);
351 let response = create_success_response(Some(JsonRpcId::Number(300)), result_data.clone());
352
353 match response.result.unwrap() {
354 NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(value)) => {
355 assert_eq!(value, result_data);
356 assert!(value.is_number());
357 }
358 _ => unreachable!("Expected EVM RawRpcResult"),
359 }
360 }
361
362 #[test]
363 fn test_create_success_response_string_result() {
364 let result_data = json!("test string");
365 let response = create_success_response(Some(JsonRpcId::Number(400)), result_data.clone());
366
367 match response.result.unwrap() {
368 NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(value)) => {
369 assert_eq!(value, result_data);
370 assert!(value.is_string());
371 }
372 _ => unreachable!("Expected EVM RawRpcResult"),
373 }
374 }
375
376 #[test]
377 fn test_create_success_response_array_result() {
378 let result_data = json!([1, 2, 3, "test", true, null]);
379 let response = create_success_response(Some(JsonRpcId::Number(500)), result_data.clone());
380
381 match response.result.unwrap() {
382 NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(value)) => {
383 assert_eq!(value, result_data);
384 assert!(value.is_array());
385 assert_eq!(value.as_array().unwrap().len(), 6);
386 }
387 _ => unreachable!("Expected EVM RawRpcResult"),
388 }
389 }
390
391 #[test]
392 fn test_create_success_response_complex_object() {
393 let result_data = json!({
394 "transactions": [
395 {"hash": "0x123", "value": "1000000000000000000"},
396 {"hash": "0x456", "value": "2000000000000000000"}
397 ],
398 "blockNumber": "0x1a2b3c",
399 "timestamp": 1234567890,
400 "gasUsed": "0x5208",
401 "metadata": {
402 "network": "mainnet",
403 "version": "1.0",
404 "features": ["eip1559", "eip2930"]
405 },
406 "isEmpty": false,
407 "nullField": null
408 });
409
410 let response = create_success_response(Some(JsonRpcId::Number(600)), result_data.clone());
411
412 match response.result.unwrap() {
413 NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(value)) => {
414 assert_eq!(value, result_data);
415 assert!(value.is_object());
416 assert_eq!(value["blockNumber"], "0x1a2b3c");
417 assert_eq!(value["transactions"].as_array().unwrap().len(), 2);
418 assert!(value["nullField"].is_null());
419 }
420 _ => unreachable!("Expected EVM RawRpcResult"),
421 }
422 }
423
424 #[test]
425 fn test_create_success_response_large_object() {
426 let mut large_object = json!({});
427 let object = large_object.as_object_mut().unwrap();
428
429 for i in 0..100 {
431 object.insert(format!("field_{}", i), json!(format!("value_{}", i)));
432 }
433
434 let response = create_success_response(Some(JsonRpcId::Number(700)), large_object.clone());
435
436 match response.result.unwrap() {
437 NetworkRpcResult::Evm(EvmRpcResult::RawRpcResult(value)) => {
438 assert_eq!(value, large_object);
439 assert_eq!(value.as_object().unwrap().len(), 100);
440 }
441 _ => unreachable!("Expected EVM RawRpcResult"),
442 }
443 }
444
445 #[test]
446 fn test_map_provider_error_invalid_address() {
447 let error = ProviderError::InvalidAddress("invalid address".to_string());
448 let (code, _message) = map_provider_error(&error);
449
450 assert_eq!(code, RpcErrorCodes::INVALID_PARAMS);
451 }
452
453 #[test]
454 fn test_map_provider_error_invalid_address_empty() {
455 let error = ProviderError::InvalidAddress("".to_string());
456 let (code, _message) = map_provider_error(&error);
457
458 assert_eq!(code, RpcErrorCodes::INVALID_PARAMS);
459 }
460
461 #[test]
462 fn test_map_provider_error_network_configuration() {
463 let error = ProviderError::NetworkConfiguration("network config error".to_string());
464 let (code, _message) = map_provider_error(&error);
465
466 assert_eq!(code, OpenZeppelinErrorCodes::NETWORK_CONFIGURATION);
467 }
468
469 #[test]
470 fn test_map_provider_error_network_configuration_empty() {
471 let error = ProviderError::NetworkConfiguration("".to_string());
472 let (code, _message) = map_provider_error(&error);
473
474 assert_eq!(code, OpenZeppelinErrorCodes::NETWORK_CONFIGURATION);
475 }
476
477 #[test]
478 fn test_map_provider_error_timeout() {
479 let error = ProviderError::Timeout;
480 let (code, _message) = map_provider_error(&error);
481
482 assert_eq!(code, OpenZeppelinErrorCodes::TIMEOUT);
483 }
484
485 #[test]
486 fn test_map_provider_error_rate_limited() {
487 let error = ProviderError::RateLimited;
488 let (code, _message) = map_provider_error(&error);
489
490 assert_eq!(code, OpenZeppelinErrorCodes::RATE_LIMITED);
491 }
492
493 #[test]
494 fn test_map_provider_error_bad_gateway() {
495 let error = ProviderError::BadGateway;
496 let (code, _message) = map_provider_error(&error);
497
498 assert_eq!(code, OpenZeppelinErrorCodes::BAD_GATEWAY);
499 }
500
501 #[test]
502 fn test_map_provider_error_request_error_400() {
503 let error = ProviderError::RequestError {
504 error: "Bad request".to_string(),
505 status_code: 400,
506 };
507 let (code, _message) = map_provider_error(&error);
508
509 assert_eq!(code, OpenZeppelinErrorCodes::REQUEST_ERROR);
510 }
511
512 #[test]
513 fn test_map_provider_error_request_error_500() {
514 let error = ProviderError::RequestError {
515 error: "Internal server error".to_string(),
516 status_code: 500,
517 };
518 let (code, _message) = map_provider_error(&error);
519
520 assert_eq!(code, OpenZeppelinErrorCodes::REQUEST_ERROR);
521 }
522
523 #[test]
524 fn test_map_provider_error_request_error_empty_message() {
525 let error = ProviderError::RequestError {
526 error: "".to_string(),
527 status_code: 404,
528 };
529 let (code, _message) = map_provider_error(&error);
530
531 assert_eq!(code, OpenZeppelinErrorCodes::REQUEST_ERROR);
532 }
533
534 #[test]
535 fn test_map_provider_error_request_error_zero_status() {
536 let error = ProviderError::RequestError {
537 error: "No status".to_string(),
538 status_code: 0,
539 };
540 let (code, _message) = map_provider_error(&error);
541
542 assert_eq!(code, OpenZeppelinErrorCodes::REQUEST_ERROR);
543 }
544
545 #[test]
546 fn test_map_provider_error_other() {
547 let error = ProviderError::Other("some other error".to_string());
548 let (code, _message) = map_provider_error(&error);
549
550 assert_eq!(code, RpcErrorCodes::INTERNAL_ERROR);
551 }
552
553 #[test]
554 fn test_map_provider_error_other_empty() {
555 let error = ProviderError::Other("".to_string());
556 let (code, _message) = map_provider_error(&error);
557
558 assert_eq!(code, RpcErrorCodes::INTERNAL_ERROR);
559 }
560
561 #[test]
562 fn test_map_provider_error_solana_rpc_error() {
563 let solana_error = SolanaProviderError::RpcError("Solana RPC failed".to_string());
564 let error = ProviderError::SolanaRpcError(solana_error);
565 let (code, _message) = map_provider_error(&error);
566
567 assert_eq!(code, RpcErrorCodes::INTERNAL_ERROR);
569 }
570
571 #[test]
572 fn test_map_provider_error_solana_invalid_address() {
573 let solana_error =
574 SolanaProviderError::InvalidAddress("Invalid Solana address".to_string());
575 let error = ProviderError::SolanaRpcError(solana_error);
576 let (code, _message) = map_provider_error(&error);
577
578 assert_eq!(code, RpcErrorCodes::INTERNAL_ERROR);
580 }
581
582 #[test]
583 fn test_map_provider_error_solana_selector_error() {
584 let selector_error = RpcSelectorError::NoProviders;
585 let solana_error = SolanaProviderError::SelectorError(selector_error);
586 let error = ProviderError::SolanaRpcError(solana_error);
587 let (code, _message) = map_provider_error(&error);
588
589 assert_eq!(code, RpcErrorCodes::INTERNAL_ERROR);
591 }
592
593 #[test]
594 fn test_map_provider_error_solana_network_configuration() {
595 let solana_error =
596 SolanaProviderError::NetworkConfiguration("Solana network config error".to_string());
597 let error = ProviderError::SolanaRpcError(solana_error);
598 let (code, _message) = map_provider_error(&error);
599
600 assert_eq!(code, RpcErrorCodes::INTERNAL_ERROR);
602 }
603
604 #[test]
605 fn test_map_provider_error_wildcard_pattern() {
606 let test_cases = vec![
609 ProviderError::SolanaRpcError(SolanaProviderError::RpcError("test".to_string())),
610 ProviderError::SolanaRpcError(SolanaProviderError::InvalidAddress("test".to_string())),
611 ProviderError::SolanaRpcError(SolanaProviderError::NetworkConfiguration(
612 "test".to_string(),
613 )),
614 ProviderError::SolanaRpcError(SolanaProviderError::SelectorError(
615 RpcSelectorError::NoProviders,
616 )),
617 ];
618
619 for error in test_cases {
620 let (code, _message) = map_provider_error(&error);
621 assert_eq!(code, RpcErrorCodes::INTERNAL_ERROR);
622 }
623 }
624
625 #[test]
626 fn test_integration_error_response_with_mapped_provider_error() {
627 let provider_error = ProviderError::InvalidAddress("0xinvalid".to_string());
628 let (error_code, error_message) = map_provider_error(&provider_error);
629
630 let response = create_error_response(
631 Some(JsonRpcId::Number(999)),
632 error_code,
633 error_message,
634 "Invalid address provided",
635 );
636
637 assert_eq!(response.id, Some(JsonRpcId::Number(999)));
638 assert_eq!(response.jsonrpc, "2.0");
639 assert!(response.result.is_none());
640
641 let error = response.error.unwrap();
642 assert_eq!(error.code, RpcErrorCodes::INVALID_PARAMS);
643 assert!(!error.message.is_empty());
644 assert!(!error.description.is_empty());
645 }
646
647 #[test]
648 fn test_integration_all_provider_errors_to_responses() {
649 let test_cases = vec![
650 (
651 ProviderError::InvalidAddress("test".to_string()),
652 RpcErrorCodes::INVALID_PARAMS,
653 ),
654 (
655 ProviderError::NetworkConfiguration("test".to_string()),
656 OpenZeppelinErrorCodes::NETWORK_CONFIGURATION,
657 ),
658 (ProviderError::Timeout, OpenZeppelinErrorCodes::TIMEOUT),
659 (
660 ProviderError::RateLimited,
661 OpenZeppelinErrorCodes::RATE_LIMITED,
662 ),
663 (
664 ProviderError::BadGateway,
665 OpenZeppelinErrorCodes::BAD_GATEWAY,
666 ),
667 (
668 ProviderError::RequestError {
669 error: "test".to_string(),
670 status_code: 400,
671 },
672 OpenZeppelinErrorCodes::REQUEST_ERROR,
673 ),
674 (
675 ProviderError::Other("test".to_string()),
676 RpcErrorCodes::INTERNAL_ERROR,
677 ),
678 ];
679
680 for (provider_error, expected_code) in test_cases {
681 let (error_code, error_message) = map_provider_error(&provider_error);
682 let response = create_error_response(
683 Some(JsonRpcId::Number(1)),
684 error_code,
685 error_message,
686 "Test integration",
687 );
688
689 assert_eq!(response.id, Some(JsonRpcId::Number(1)));
690 assert_eq!(response.jsonrpc, "2.0");
691 assert!(response.result.is_none());
692
693 let error = response.error.unwrap();
694 assert_eq!(error.code, expected_code);
695 assert!(!error.message.is_empty());
696 }
697 }
698
699 #[test]
700 fn test_response_structure_consistency() {
701 let success_response =
703 create_success_response(Some(JsonRpcId::Number(100)), json!({"status": "ok"}));
704 let error_response = create_error_response(
705 Some(JsonRpcId::Number(100)),
706 -32603,
707 "Internal error",
708 "Test error",
709 );
710
711 assert_eq!(success_response.id, error_response.id);
713 assert_eq!(success_response.jsonrpc, error_response.jsonrpc);
714
715 assert!(success_response.result.is_some());
717 assert!(success_response.error.is_none());
718
719 assert!(error_response.result.is_none());
721 assert!(error_response.error.is_some());
722 }
723}