11import axios from 'axios'
2+ import { CircuitBreaker , retryWithBackoff } from '../../../../utils/CircuitBreaker'
23
34const SIRV_CONFIG = {
45 clientId : process . env . SIRV_CLIENT_ID_RO ?? null ,
@@ -9,9 +10,27 @@ const client = axios.create({
910 baseURL : 'https://api.sirv.com/v2' ,
1011 headers : {
1112 'content-type' : 'application/json'
12- }
13+ } ,
14+ timeout : 30000 // 30 second timeout
1315} )
1416
17+ // Add axios interceptors for better error handling
18+ client . interceptors . response . use (
19+ response => response ,
20+ async error => {
21+ console . error ( 'Sirv API error:' , {
22+ status : error . response ?. status ,
23+ statusText : error . response ?. statusText ,
24+ data : error . response ?. data ,
25+ config : {
26+ method : error . config ?. method ,
27+ url : error . config ?. url
28+ }
29+ } )
30+ return await Promise . reject ( error )
31+ }
32+ )
33+
1534const headers = {
1635 'content-type' : 'application/json'
1736}
@@ -21,23 +40,33 @@ interface TokenParamsType {
2140 clientSecret : string | null
2241}
2342
43+ // Circuit breaker for Sirv API calls
44+ const sirvCircuitBreaker = new CircuitBreaker ( {
45+ failureThreshold : 3 ,
46+ resetTimeout : 60000 , // 1 minute
47+ monitoringPeriod : 10000 // 10 seconds
48+ } )
49+
2450const getToken = async ( ) : Promise < string | null > => {
2551 const params : TokenParamsType = {
2652 clientId : SIRV_CONFIG . clientId ,
2753 clientSecret : SIRV_CONFIG . clientSecret
2854 }
2955
3056 try {
31- const res = await client . post (
32- '/token' ,
33- params )
57+ const res = await sirvCircuitBreaker . execute ( async ( ) => {
58+ return await retryWithBackoff ( async ( ) => {
59+ return await client . post ( '/token' , params )
60+ } , 3 , 1000 , 5000 )
61+ } )
3462
3563 if ( res . status === 200 ) {
3664 return res . data . token
3765 }
3866 } catch ( e ) {
39- console . error ( e )
40- process . exit ( 1 )
67+ console . error ( 'Failed to get Sirv token after retries:' , e )
68+ // Don't exit process - let the app continue without Sirv functionality
69+ return null
4170 }
4271 return null
4372}
@@ -57,22 +86,31 @@ interface FileMetadaata {
5786 * @returns
5887 */
5988export const getFileInfo = async ( filename : string ) : Promise < FileMetadaata > => {
60- const res = await client . get (
61- '/files/stat?filename=' + encodeURIComponent ( filename ) ,
62- {
63- headers : {
64- ...headers ,
65- Authorization : `bearer ${ token } `
66- }
67- }
68- )
69-
70- if ( res . status === 200 ) {
71- const { ctime, mtime } = res . data
72- return ( {
73- btime : new Date ( ctime ) ,
74- mtime : new Date ( mtime )
89+ try {
90+ const res = await sirvCircuitBreaker . execute ( async ( ) => {
91+ return await retryWithBackoff ( async ( ) => {
92+ return await client . get (
93+ '/files/stat?filename=' + encodeURIComponent ( filename ) ,
94+ {
95+ headers : {
96+ ...headers ,
97+ Authorization : `bearer ${ token } `
98+ }
99+ }
100+ )
101+ } , 3 , 1000 , 5000 )
75102 } )
103+
104+ if ( res . status === 200 ) {
105+ const { ctime, mtime } = res . data
106+ return ( {
107+ btime : new Date ( ctime ) ,
108+ mtime : new Date ( mtime )
109+ } )
110+ }
111+ throw new Error ( 'Sirv API.getFileInfo() error: ' + String ( res . statusText ) )
112+ } catch ( e ) {
113+ console . error ( 'Failed to get file info after retries:' , e )
114+ throw e
76115 }
77- throw new Error ( 'Sirv API.getFileInfo() error' + res . statusText )
78116}
0 commit comments