1module TwoCaptcha.Internal.Types.Exception where
2
3import Control.Exception (Exception)
4import Data.Functor (($>))
5import Data.Text (Text)
6import Network.HTTP.Client (HttpException)
7import Text.Parsec (ParseError, parse, try, (<|>))
8import Text.Parsec.Char (string)
9import Text.Parsec.String (Parser)
10
11-- | Represents a possible exception when interacting with the 2captcha API.
12data TwoCaptchaException
13 = -- | An error documented on 2captcha's website.
14 TwoCaptchaResponseException TwoCaptchaErrorCode
15 | -- | A non-200 status code was thrown. This should only appear in rare cases.
16 NetworkException HttpException
17 | -- | An unknown error occured, likely due to a change in the 2captcha API.
18 UnknownError Text
19 | -- | Solving the captcha took too long. Try setting a higher timeout duration?
20 SolvingTimeout
21 deriving (Show)
22
23instance Exception TwoCaptchaException
24
25-- | Possible errors when using the 2captcha API.
26data TwoCaptchaErrorCode
27 = -- | The api key you provided is invalid. Please ensure it is 32 characters long.
28 WrongUserKey
29 | -- | The key you've provided does not exist.
30 KeyDoesNotExist
31 | -- | You don't have funds in your account.
32 ZeroBalance
33 | -- | The __pageurl__ parameter is missing in your request.
34 PageUrlMissing
35 | -- |
36 -- You can receive this error in two cases:
37 --
38 -- 1. __If you solve token-based captchas (reCAPTCHA, hCaptcha, ArkoseLabs FunCaptcha, GeeTest, etc):__
39 -- the queue of your captchas that are not distributed to workers is too long.
40 -- Queue limit changes dynamically and depends on total amount of captchas awaiting solution and usually it’s between 50 and 100 captchas.
41 --
42 -- 2. __If you solve Normal Captcha:__ your maximum rate for normal captchas is lower than current rate on the server.
43 -- You can change your maximum rate in <https://2captcha.com/setting your account's settings.>
44 NoSlotAvailable
45 | -- | Image size is less than 100 bytes.
46 ZeroCaptchaFileSize
47 | -- | Image size is more than 100 kB.
48 TooBigCaptchaFileSize
49 | -- | Image file has unsupported extension. Accepted extensions: jpg, jpeg, gif, png.
50 WrongFileExtension
51 | -- | Server can't recognize image file type.
52 ImageTypeNotSupported
53 | -- |
54 -- Server can't get file data from your POST-request.
55 -- That happens if your POST-request is malformed or base64 data is not a valid base64 image.
56 UploadFailure
57 | -- | The request is sent from the IP that is not on the list of your allowed IPs.
58 IpNotAllowed
59 | -- | Your IP address is banned due to many frequent attempts to access the server using wrong authorization keys.
60 IpBanned
61 | -- |
62 -- You can get this error code when sending reCAPTCHA V2. This happens if your request contains invalid pair of googlekey and pageurl.
63 -- The common reason for that is that reCAPTCHA is loaded inside an iframe hosted on another domain/subdomain.
64 BadTokenOrPageUrl
65 | -- | You can get this error code when sending reCAPTCHA V2. That means that sitekey value provided in your request is incorrect: it's blank or malformed.
66 GoogleKeyInvalid
67 | -- | The __googlekey__ parameter is missing in your request.
68 GoogleKeyMissing
69 | -- |
70 -- You've sent an image that is marked in 2captcha's database as unrecognizable.
71 -- Usually that happens if the website where you found the captcha stopped sending you captchas and started to send a "deny access" image.
72 CaptchaImageBlocked
73 | -- | You are sending too many unrecognizable images.
74 TooManyBadImages
75 | -- |
76 -- You made more than 60 requests to in.php within 3 seconds.
77 -- Your account is banned for 10 seconds. Ban will be lifted automatically.
78 RateLimited
79 | -- |
80 -- You received the error 'NoSlotAvailable' 120 times in one minute because your current bid is lower than current bid on the server.
81 --
82 -- Blocking time: 10 minutes.
83 Error1001
84 | -- |
85 -- You received the error 'ZeroBalance' 120 times in one minute because your balance is zero.
86 --
87 -- Blocking time: 5 minutes.
88 Error1002
89 | -- |
90 -- You received the error 'NoSlotAvailable' because you are uploading many captchas and server has a long queue of your captchas that are not distributed to workers.
91 -- You received three times more errors than amount of captchas you sent (but not less than 120 errors). Increase the timeout if you see this error.
92 --
93 -- Blocking time: 30 seconds.
94 Error1003
95 | -- | Your IP address is blocked because there were 5 requests with incorrect API key from your IP.
96 Error1004
97 | -- |
98 -- You are making too many requests to res.php to get answers.
99 --
100 --
101 -- 2captcha uses the following rule to block your account: R > C * 20 + 1200
102 --
103 -- Where:
104 --
105 -- * R - the amount of your requests
106 --
107 -- * C - the amount of captchas you've uploaded
108 --
109 -- That means that you don't have to make more than 20 requests to res.php per each captcha.
110 -- Please remember that balance request sent to res.php also counts!
111 --
112 -- To get your answer faster without a risk to be blocked you can use <https://2captcha.com/2captcha-api#pingback pingback> feature and 2captcha will send you the answer when your captcha is solved.
113 --
114 -- Blocking time: 10 minutes.
115 Error1005
116 | -- |
117 -- The error code is returned if some required parameters are missing in your request or the values have incorrect format.
118 -- For example if you submit <https://2captcha.com/2captcha-api#grid Grid images> but your request is missing an instruction for workers.
119 --
120 -- Blocking time: 5 minutes.
121 BadParameters
122 | -- | You can get this error code when sending a captcha via proxy server which is marked as BAD by the 2captcha API.
123 BadProxy
124 | -- | Your captcha is not solved yet.
125 CaptchaNotReady
126 | -- |
127 -- 2captcha was unable to solve your captcha - three of their workers were unable solve it or they didn't get an answer within 90 seconds (300 seconds for reCAPTCHA V2).
128 --
129 -- You will not be charged for that request.
130 CaptchaUnsolvable
131 | -- | You've provided captcha ID in wrong format. The ID can contain numbers only.
132 WrongIdFormat
133 | -- | You provided an invalid captcha id.
134 WrongCaptchaId
135 | -- | Error is returned when 100% accuracy feature is enabled. The error means that max numbers of tries is reached but min number of matches not found.
136 BadDuplicates
137 | -- |
138 -- Error is returned to your <https://2captcha.com/2captcha-api#complain report> request if you already complained lots of correctly solved captchas (more than 40%).
139 -- Or if more than 15 minutes passed after you submitted the captcha.
140 ReportNotRecorded
141 | -- | Error is returned to your <https://2captcha.com/2captcha-api#complain report request> if you are trying to report the same captcha more than once.
142 DuplicateReport
143 | -- |
144 -- You can receive this error code when registering a <https://2captcha.com/2captcha-api#pingback pingback (callback)> IP or domain.
145 --
146 -- This happens if your request is coming from an IP address that doesn't match the IP address of your pingback IP or domain.
147 InvalidPingbackIp
148 | -- |
149 -- You can receive this error code when sending <https://2captcha.com/2captcha-api#solving_geetest GeeTest>.
150 -- This error means the __challenge__ value you provided is expired.
151 TokenExpired
152 | -- | Action parameter is missing or no value is provided for __action__ parameter.
153 EmptyAction
154 | -- |
155 -- You can get this error code if we were unable to load a captcha through your proxy server.
156 -- The proxy will be marked as BAD by our API and we will not accept requests with the proxy during 10 minutes.
157 -- You will recieve ERROR_BAD_PROXY code from in.php API endpoint in such case.
158 ProxyConnectionFailed
159 deriving (Show, Eq)
160
161-- | The raw error code provided by 2captcha.
162errorCode :: TwoCaptchaErrorCode -> String
163errorCode WrongUserKey = "ERROR_WRONG_USER_KEY"
164errorCode KeyDoesNotExist = "ERROR_KEY_DOES_NOT_EXIST"
165errorCode ZeroBalance = "ERROR_ZERO_BALANCE"
166errorCode PageUrlMissing = "ERROR_PAGEURL"
167errorCode NoSlotAvailable = "ERROR_NO_SLOT_AVAILABLE"
168errorCode ZeroCaptchaFileSize = "ERROR_ZERO_CAPTCHA_FILESIZE"
169errorCode TooBigCaptchaFileSize = "ERROR_TOO_BIG_CAPTCHA_FILESIZE"
170errorCode WrongFileExtension = "ERROR_WRONG_FILE_EXTENSION"
171errorCode ImageTypeNotSupported = "ERROR_IMAGE_TYPE_NOT_SUPPORTED"
172errorCode UploadFailure = "ERROR_UPLOAD"
173errorCode IpNotAllowed = "ERROR_IP_NOT_ALLOWED"
174errorCode IpBanned = "IP_BANNED"
175errorCode BadTokenOrPageUrl = "ERROR_BAD_TOKEN_OR_PAGEURL"
176errorCode GoogleKeyInvalid = "ERROR_GOOGLEKEY"
177errorCode GoogleKeyMissing = "ERROR_WRONG_GOOGLEKEY"
178errorCode CaptchaImageBlocked = "ERROR_CAPTCHAIMAGE_BLOCKED"
179errorCode TooManyBadImages = "TOO_MANY_BAD_IMAGES"
180errorCode RateLimited = "MAX_USER_TURN"
181errorCode Error1001 = "ERROR: 1001"
182errorCode Error1002 = "ERROR: 1002"
183errorCode Error1003 = "ERROR: 1003"
184errorCode Error1004 = "ERROR: 1004"
185errorCode Error1005 = "ERROR: 1005"
186errorCode BadParameters = "ERROR_BAD_PARAMETERS"
187errorCode BadProxy = "ERROR_BAD_PROXY"
188errorCode CaptchaNotReady = "CAPCHA_NOT_READY"
189errorCode CaptchaUnsolvable = "ERROR_CAPTCHA_UNSOLVABLE"
190errorCode WrongIdFormat = "ERROR_WRONG_ID_FORMAT"
191errorCode WrongCaptchaId = "ERROR_WRONG_CAPTCHA_ID"
192errorCode BadDuplicates = "ERROR_BAD_DUPLICATES"
193errorCode ReportNotRecorded = "ERROR_REPORT_NOT_RECORDED"
194errorCode DuplicateReport = "ERROR_DUPLICATE_REPORT"
195errorCode InvalidPingbackIp = "ERROR_IP_ADDRES"
196errorCode TokenExpired = "ERROR_TOKEN_EXPIRED"
197errorCode EmptyAction = "ERROR_EMPTY_ACTION"
198errorCode ProxyConnectionFailed = "ERROR_PROXY_CONNECTION_FAILED"
199
200-- | Parser instance for parsing an error code to a 'TwoCaptchaErrorCode'.
201errorParser :: Parser TwoCaptchaErrorCode
202errorParser =
203 try (string (errorCode WrongUserKey) $> WrongUserKey)
204 <|> try (string (errorCode KeyDoesNotExist) $> KeyDoesNotExist)
205 <|> try (string (errorCode ZeroBalance) $> ZeroBalance)
206 <|> try (string (errorCode PageUrlMissing) $> PageUrlMissing)
207 <|> try (string (errorCode NoSlotAvailable) $> NoSlotAvailable)
208 <|> try (string (errorCode ZeroCaptchaFileSize) $> ZeroCaptchaFileSize)
209 <|> try (string (errorCode TooBigCaptchaFileSize) $> TooBigCaptchaFileSize)
210 <|> try (string (errorCode WrongFileExtension) $> WrongFileExtension)
211 <|> try (string (errorCode ImageTypeNotSupported) $> ImageTypeNotSupported)
212 <|> try (string (errorCode UploadFailure) $> UploadFailure)
213 <|> try (string (errorCode IpNotAllowed) $> IpNotAllowed)
214 <|> try (string (errorCode IpBanned) $> IpBanned)
215 <|> try (string (errorCode BadTokenOrPageUrl) $> BadTokenOrPageUrl)
216 <|> try (string (errorCode GoogleKeyInvalid) $> GoogleKeyInvalid)
217 <|> try (string (errorCode GoogleKeyMissing) $> GoogleKeyMissing)
218 <|> try (string (errorCode CaptchaImageBlocked) $> CaptchaImageBlocked)
219 <|> try (string (errorCode TooManyBadImages) $> TooManyBadImages)
220 <|> try (string (errorCode RateLimited) $> RateLimited)
221 <|> try (string (errorCode Error1001) $> Error1001)
222 <|> try (string (errorCode Error1002) $> Error1002)
223 <|> try (string (errorCode Error1003) $> Error1003)
224 <|> try (string (errorCode Error1004) $> Error1004)
225 <|> try (string (errorCode Error1005) $> Error1005)
226 <|> try (string (errorCode BadParameters) $> BadParameters)
227 <|> try (string (errorCode BadProxy) $> BadProxy)
228 <|> try (string (errorCode CaptchaNotReady) $> CaptchaNotReady)
229 <|> try (string (errorCode CaptchaUnsolvable) $> CaptchaUnsolvable)
230 <|> try (string (errorCode WrongIdFormat) $> WrongIdFormat)
231 <|> try (string (errorCode WrongCaptchaId) $> WrongCaptchaId)
232 <|> try (string (errorCode BadDuplicates) $> BadDuplicates)
233 <|> try (string (errorCode ReportNotRecorded) $> ReportNotRecorded)
234 <|> try (string (errorCode DuplicateReport) $> DuplicateReport)
235 <|> try (string (errorCode InvalidPingbackIp) $> InvalidPingbackIp)
236 <|> try (string (errorCode TokenExpired) $> TokenExpired $> TokenExpired $> TokenExpired $> TokenExpired)
237 <|> try (string (errorCode EmptyAction) $> EmptyAction)
238 <|> string (errorCode ProxyConnectionFailed) $> ProxyConnectionFailed
239
240-- | Read an error code as its corresponding 'TwoCaptchaErrorCode'.
241readErrorCode :: String -> Either ParseError TwoCaptchaErrorCode
242readErrorCode = parse errorParser ""