11#![ doc = include_str ! ( "../README.md" ) ]
22
3- use anyhow:: { Context , anyhow} ;
43use reqwest:: Client ;
5- use reqwest:: header:: { HeaderMap , HeaderValue , InvalidHeaderValue } ;
4+ use reqwest:: header:: { HeaderValue , InvalidHeaderValue } ;
65use secrecy:: { ExposeSecret , SecretString } ;
6+ use thiserror:: Error ;
77use tracing:: { debug, instrument, trace} ;
88
9+ #[ derive( Debug , Error ) ]
10+ pub enum Error {
11+ #[ error( "Wildcard invalidations are not supported for Fastly" ) ]
12+ WildcardNotSupported ,
13+
14+ #[ error( "Invalid API token format" ) ]
15+ InvalidApiToken ( #[ from] InvalidHeaderValue ) ,
16+
17+ #[ error( "Failed to `POST {url}`{}: {source}" , status. map( |s| format!( " (status: {})" , s) ) . unwrap_or_default( ) ) ]
18+ PurgeFailed {
19+ url : String ,
20+ status : Option < reqwest:: StatusCode > ,
21+ #[ source]
22+ source : reqwest:: Error ,
23+ } ,
24+ }
25+
926#[ derive( Debug ) ]
1027pub struct Fastly {
1128 client : Client ,
@@ -30,7 +47,7 @@ impl Fastly {
3047 /// More information on Fastly's APIs for cache invalidations can be found here:
3148 /// <https://developer.fastly.com/reference/api/purging/>
3249 #[ instrument( skip( self ) ) ]
33- pub async fn purge_both_domains ( & self , base_domain : & str , path : & str ) -> anyhow :: Result < ( ) > {
50+ pub async fn purge_both_domains ( & self , base_domain : & str , path : & str ) -> Result < ( ) , Error > {
3451 self . purge ( base_domain, path) . await ?;
3552
3653 let prefixed_domain = format ! ( "fastly-{base_domain}" ) ;
@@ -48,11 +65,9 @@ impl Fastly {
4865 /// More information on Fastly's APIs for cache invalidations can be found here:
4966 /// <https://developer.fastly.com/reference/api/purging/>
5067 #[ instrument( skip( self ) ) ]
51- pub async fn purge ( & self , domain : & str , path : & str ) -> anyhow :: Result < ( ) > {
68+ pub async fn purge ( & self , domain : & str , path : & str ) -> Result < ( ) , Error > {
5269 if path. contains ( '*' ) {
53- return Err ( anyhow ! (
54- "wildcard invalidations are not supported for Fastly"
55- ) ) ;
70+ return Err ( Error :: WildcardNotSupported ) ;
5671 }
5772
5873 let path = path. trim_start_matches ( '/' ) ;
@@ -67,7 +82,11 @@ impl Fastly {
6782 . header ( "Fastly-Key" , self . token_header_value ( ) ?)
6883 . send ( )
6984 . await
70- . context ( "failed to send invalidation request to Fastly" ) ?;
85+ . map_err ( |source| Error :: PurgeFailed {
86+ url : url. clone ( ) ,
87+ status : None ,
88+ source,
89+ } ) ?;
7190
7291 let status = response. status ( ) ;
7392
@@ -86,7 +105,11 @@ impl Fastly {
86105 "invalidation request to Fastly failed"
87106 ) ;
88107
89- Err ( error) . with_context ( || format ! ( "failed to purge {url}" ) )
108+ Err ( Error :: PurgeFailed {
109+ url,
110+ status : Some ( status) ,
111+ source : error,
112+ } )
90113 }
91114 }
92115 }
0 commit comments