1use thiserror::Error;
2use url::Url;
3
4use crate::errors::RequestFailure;
5
6#[derive(Debug, Error)]
7pub enum VerificationError {
8 #[error("[E004] Compilation failed: {0}")]
9 CompilationFailure(String),
10
11 #[error("[E005] Verification failed: {0}")]
12 VerificationFailure(String),
13}
14
15impl VerificationError {
16 pub const fn error_code(&self) -> &'static str {
17 match self {
18 Self::CompilationFailure(_) => "E004",
19 Self::VerificationFailure(_) => "E005",
20 }
21 }
22
23 pub fn suggestions(&self) -> Vec<&'static str> {
24 match self {
25 Self::CompilationFailure(msg) => {
26 let mut suggestions = vec![
27 "Check that all dependencies are properly declared in Scarb.toml",
28 "Verify that the contract syntax is correct",
29 "Ensure all imports are valid and accessible",
30 "Check for typos in function names and variable declarations",
31 ];
32
33 if msg.contains("not found") {
34 suggestions.push("Verify that all modules and dependencies are available");
35 }
36
37 if msg.contains("syntax") {
38 suggestions.push("Review the Cairo syntax documentation");
39 }
40
41 suggestions
42 }
43 Self::VerificationFailure(msg) => {
44 let mut suggestions = vec![
45 "Ensure the compiled class hash matches the declared class hash",
46 "Verify that the source code corresponds to the deployed contract",
47 "Check that all dependencies are at the correct versions",
48 "Confirm that the contract was compiled with the same Cairo version",
49 ];
50
51 if msg.contains("hash") {
52 suggestions.push("Double-check the class hash value");
53 }
54
55 if msg.contains("version") {
56 suggestions.push("Verify Cairo compiler version compatibility");
57 }
58
59 suggestions
60 }
61 }
62 }
63}
64
65#[derive(Debug, Error)]
66pub enum ApiClientError {
67 #[error("[E006] Invalid base URL: {0}\n\nSuggestions:\n • Provide a valid HTTP or HTTPS URL\n • Example: https://api.example.com\n • Ensure the URL includes the protocol (http:// or https://)")]
68 CannotBeBase(Url),
69
70 #[error(transparent)]
71 Reqwest(#[from] reqwest::Error),
72
73 #[error("[E007] Verification job is still in progress\n\nSuggestions:\n • Wait a moment before checking again\n • Use --wait to automatically wait for completion\n • Check the job status periodically")]
74 InProgress,
75
76 #[error(transparent)]
77 Failure(#[from] RequestFailure),
78
79 #[error("[E008] Job '{0}' not found\n\nSuggestions:\n • Check that the job ID is correct\n • Verify the job was submitted successfully\n • The job may have expired from the server\n • Try submitting a new verification request")]
80 JobNotFound(String),
81
82 #[error(transparent)]
83 Verify(#[from] VerificationError),
84
85 #[error(transparent)]
86 IoError(#[from] std::io::Error),
87
88 #[error("[E009] Invalid URL format: {0}\n\nSuggestions:\n • Check the URL format is correct\n • Ensure proper encoding of special characters\n • Use absolute URLs with protocol (http:// or https://)")]
89 UrlCannotBeBase(#[from] url::ParseError),
90}
91
92impl ApiClientError {
93 pub const fn error_code(&self) -> &'static str {
94 match self {
95 Self::CannotBeBase(_) => "E006",
96 Self::Reqwest(_) | Self::IoError(_) => "E999", Self::InProgress => "E007",
98 Self::Failure(f) => f.error_code().as_str(),
99 Self::JobNotFound(_) => "E008",
100 Self::Verify(v) => v.error_code(),
101 Self::UrlCannotBeBase(_) => "E009",
102 }
103 }
104}