@@ -17,7 +17,9 @@ use std::str::FromStr;
1717use bitcoin:: consensus:: { deserialize, serialize} ;
1818use bitcoin:: hashes:: hex:: FromHex ;
1919use bitcoin:: hashes:: { sha256, Hash } ;
20- use bitcoin:: { Block , BlockHash , block:: Header as BlockHeader , MerkleBlock , Script , Transaction , Txid } ;
20+ use bitcoin:: {
21+ block:: Header as BlockHeader , Block , BlockHash , MerkleBlock , Script , Transaction , Txid ,
22+ } ;
2123use bitcoin_internals:: hex:: display:: DisplayHex ;
2224
2325#[ allow( unused_imports) ]
@@ -68,7 +70,14 @@ impl AsyncClient {
6870 return Ok ( None ) ;
6971 }
7072
71- Ok ( Some ( deserialize ( & resp. error_for_status ( ) ?. bytes ( ) . await ?) ?) )
73+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
74+ Err ( Error :: HttpResponse {
75+ status : resp. status ( ) . as_u16 ( ) ,
76+ message : resp. text ( ) . await ?,
77+ } )
78+ } else {
79+ Ok ( Some ( deserialize ( & resp. bytes ( ) . await ?) ?) )
80+ }
7281 }
7382
7483 /// Get a [`Transaction`] given its [`Txid`].
@@ -96,7 +105,14 @@ impl AsyncClient {
96105 return Ok ( None ) ;
97106 }
98107
99- Ok ( Some ( Txid :: from_str ( & resp. text ( ) . await ?) ?) )
108+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
109+ Err ( Error :: HttpResponse {
110+ status : resp. status ( ) . as_u16 ( ) ,
111+ message : resp. text ( ) . await ?,
112+ } )
113+ } else {
114+ Ok ( Some ( Txid :: from_str ( & resp. text ( ) . await ?) ?) )
115+ }
100116 }
101117
102118 /// Get the status of a [`Transaction`] given its [`Txid`].
@@ -106,8 +122,14 @@ impl AsyncClient {
106122 . get ( & format ! ( "{}/tx/{}/status" , self . url, txid) )
107123 . send ( )
108124 . await ?;
109-
110- Ok ( resp. error_for_status ( ) ?. json ( ) . await ?)
125+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
126+ Err ( Error :: HttpResponse {
127+ status : resp. status ( ) . as_u16 ( ) ,
128+ message : resp. text ( ) . await ?,
129+ } )
130+ } else {
131+ Ok ( resp. json ( ) . await ?)
132+ }
111133 }
112134
113135 #[ deprecated(
@@ -128,9 +150,15 @@ impl AsyncClient {
128150 . send ( )
129151 . await ?;
130152
131- let header = deserialize ( & Vec :: from_hex ( & resp. text ( ) . await ?) ?) ?;
132-
133- Ok ( header)
153+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
154+ Err ( Error :: HttpResponse {
155+ status : resp. status ( ) . as_u16 ( ) ,
156+ message : resp. text ( ) . await ?,
157+ } )
158+ } else {
159+ let header = deserialize ( & Vec :: from_hex ( & resp. text ( ) . await ?) ?) ?;
160+ Ok ( header)
161+ }
134162 }
135163
136164 /// Get the [`BlockStatus`] given a particular [`BlockHash`].
@@ -141,7 +169,14 @@ impl AsyncClient {
141169 . send ( )
142170 . await ?;
143171
144- Ok ( resp. error_for_status ( ) ?. json ( ) . await ?)
172+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
173+ Err ( Error :: HttpResponse {
174+ status : resp. status ( ) . as_u16 ( ) ,
175+ message : resp. text ( ) . await ?,
176+ } )
177+ } else {
178+ Ok ( resp. json ( ) . await ?)
179+ }
145180 }
146181
147182 /// Get a [`Block`] given a particular [`BlockHash`].
@@ -155,7 +190,15 @@ impl AsyncClient {
155190 if let StatusCode :: NOT_FOUND = resp. status ( ) {
156191 return Ok ( None ) ;
157192 }
158- Ok ( Some ( deserialize ( & resp. error_for_status ( ) ?. bytes ( ) . await ?) ?) )
193+
194+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
195+ Err ( Error :: HttpResponse {
196+ status : resp. status ( ) . as_u16 ( ) ,
197+ message : resp. text ( ) . await ?,
198+ } )
199+ } else {
200+ Ok ( Some ( deserialize ( & resp. bytes ( ) . await ?) ?) )
201+ }
159202 }
160203
161204 /// Get a merkle inclusion proof for a [`Transaction`] with the given [`Txid`].
@@ -170,7 +213,14 @@ impl AsyncClient {
170213 return Ok ( None ) ;
171214 }
172215
173- Ok ( Some ( resp. error_for_status ( ) ?. json ( ) . await ?) )
216+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
217+ Err ( Error :: HttpResponse {
218+ status : resp. status ( ) . as_u16 ( ) ,
219+ message : resp. text ( ) . await ?,
220+ } )
221+ } else {
222+ Ok ( Some ( resp. json ( ) . await ?) )
223+ }
174224 }
175225
176226 /// Get a [`MerkleBlock`] inclusion proof for a [`Transaction`] with the given [`Txid`].
@@ -185,9 +235,15 @@ impl AsyncClient {
185235 return Ok ( None ) ;
186236 }
187237
188- let merkle_block = deserialize ( & Vec :: from_hex ( & resp. text ( ) . await ?) ?) ?;
189-
190- Ok ( Some ( merkle_block) )
238+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
239+ Err ( Error :: HttpResponse {
240+ status : resp. status ( ) . as_u16 ( ) ,
241+ message : resp. text ( ) . await ?,
242+ } )
243+ } else {
244+ let merkle_block = deserialize ( & Vec :: from_hex ( & resp. text ( ) . await ?) ?) ?;
245+ Ok ( Some ( merkle_block) )
246+ }
191247 }
192248
193249 /// Get the spending status of an output given a [`Txid`] and the output index.
@@ -206,19 +262,33 @@ impl AsyncClient {
206262 return Ok ( None ) ;
207263 }
208264
209- Ok ( Some ( resp. error_for_status ( ) ?. json ( ) . await ?) )
265+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
266+ Err ( Error :: HttpResponse {
267+ status : resp. status ( ) . as_u16 ( ) ,
268+ message : resp. text ( ) . await ?,
269+ } )
270+ } else {
271+ Ok ( Some ( resp. json ( ) . await ?) )
272+ }
210273 }
211274
212275 /// Broadcast a [`Transaction`] to Esplora
213276 pub async fn broadcast ( & self , transaction : & Transaction ) -> Result < ( ) , Error > {
214- self . client
277+ let resp = self
278+ . client
215279 . post ( & format ! ( "{}/tx" , self . url) )
216280 . body ( serialize ( transaction) . to_lower_hex_string ( ) )
217281 . send ( )
218- . await ?
219- . error_for_status ( ) ?;
282+ . await ?;
220283
221- Ok ( ( ) )
284+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
285+ Err ( Error :: HttpResponse {
286+ status : resp. status ( ) . as_u16 ( ) ,
287+ message : resp. text ( ) . await ?,
288+ } )
289+ } else {
290+ Ok ( ( ) )
291+ }
222292 }
223293
224294 /// Get the current height of the blockchain tip
@@ -229,7 +299,14 @@ impl AsyncClient {
229299 . send ( )
230300 . await ?;
231301
232- Ok ( resp. error_for_status ( ) ?. text ( ) . await ?. parse ( ) ?)
302+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
303+ Err ( Error :: HttpResponse {
304+ status : resp. status ( ) . as_u16 ( ) ,
305+ message : resp. text ( ) . await ?,
306+ } )
307+ } else {
308+ Ok ( resp. text ( ) . await ?. parse ( ) ?)
309+ }
233310 }
234311
235312 /// Get the [`BlockHash`] of the current blockchain tip.
@@ -240,9 +317,14 @@ impl AsyncClient {
240317 . send ( )
241318 . await ?;
242319
243- Ok ( BlockHash :: from_str (
244- & resp. error_for_status ( ) ?. text ( ) . await ?,
245- ) ?)
320+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
321+ Err ( Error :: HttpResponse {
322+ status : resp. status ( ) . as_u16 ( ) ,
323+ message : resp. text ( ) . await ?,
324+ } )
325+ } else {
326+ Ok ( BlockHash :: from_str ( & resp. text ( ) . await ?) ?)
327+ }
246328 }
247329
248330 /// Get the [`BlockHash`] of a specific block height
@@ -257,9 +339,14 @@ impl AsyncClient {
257339 return Err ( Error :: HeaderHeightNotFound ( block_height) ) ;
258340 }
259341
260- Ok ( BlockHash :: from_str (
261- & resp. error_for_status ( ) ?. text ( ) . await ?,
262- ) ?)
342+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
343+ Err ( Error :: HttpResponse {
344+ status : resp. status ( ) . as_u16 ( ) ,
345+ message : resp. text ( ) . await ?,
346+ } )
347+ } else {
348+ Ok ( BlockHash :: from_str ( & resp. text ( ) . await ?) ?)
349+ }
263350 }
264351
265352 /// Get confirmed transaction history for the specified address/scripthash,
@@ -278,27 +365,36 @@ impl AsyncClient {
278365 ) ,
279366 None => format ! ( "{}/scripthash/{:x}/txs" , self . url, script_hash) ,
280367 } ;
281- Ok ( self
282- . client
283- . get ( url)
284- . send ( )
285- . await ?
286- . error_for_status ( ) ?
287- . json :: < Vec < Tx > > ( )
288- . await ?)
368+
369+ let resp = self . client . get ( url) . send ( ) . await ?;
370+
371+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
372+ Err ( Error :: HttpResponse {
373+ status : resp. status ( ) . as_u16 ( ) ,
374+ message : resp. text ( ) . await ?,
375+ } )
376+ } else {
377+ Ok ( resp. json :: < Vec < Tx > > ( ) . await ?)
378+ }
289379 }
290380
291381 /// Get an map where the key is the confirmation target (in number of blocks)
292382 /// and the value is the estimated feerate (in sat/vB).
293383 pub async fn get_fee_estimates ( & self ) -> Result < HashMap < String , f64 > , Error > {
294- Ok ( self
384+ let resp = self
295385 . client
296386 . get ( & format ! ( "{}/fee-estimates" , self . url, ) )
297387 . send ( )
298- . await ?
299- . error_for_status ( ) ?
300- . json :: < HashMap < String , f64 > > ( )
301- . await ?)
388+ . await ?;
389+
390+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
391+ Err ( Error :: HttpResponse {
392+ status : resp. status ( ) . as_u16 ( ) ,
393+ message : resp. text ( ) . await ?,
394+ } )
395+ } else {
396+ Ok ( resp. json :: < HashMap < String , f64 > > ( ) . await ?)
397+ }
302398 }
303399
304400 /// Gets some recent block summaries starting at the tip or at `height` if provided.
@@ -311,14 +407,16 @@ impl AsyncClient {
311407 None => format ! ( "{}/blocks" , self . url) ,
312408 } ;
313409
314- Ok ( self
315- . client
316- . get ( & url)
317- . send ( )
318- . await ?
319- . error_for_status ( ) ?
320- . json ( )
321- . await ?)
410+ let resp = self . client . get ( & url) . send ( ) . await ?;
411+
412+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
413+ Err ( Error :: HttpResponse {
414+ status : resp. status ( ) . as_u16 ( ) ,
415+ message : resp. text ( ) . await ?,
416+ } )
417+ } else {
418+ Ok ( resp. json :: < Vec < BlockSummary > > ( ) . await ?)
419+ }
322420 }
323421
324422 /// Get the underlying base URL.
0 commit comments