1
1
const debug = require ( 'debug' ) ( 'codefresh:http' ) ;
2
2
const fs = require ( 'fs' ) ;
3
3
const path = require ( 'path' ) ;
4
- const rp = require ( 'request-promise ' ) ;
4
+ const request = require ( 'requestretry ' ) ;
5
5
const _ = require ( 'lodash' ) ;
6
6
const CFError = require ( 'cf-errors' ) ;
7
- const { printError } = require ( '../../interface/cli/helpers/general' ) ;
7
+ const { printError, isDebug } = require ( '../../interface/cli/helpers/general' ) ;
8
+ const config = require ( '../../logic/cli-config/Manager' ) . config ( ) ;
8
9
9
10
const { version } = JSON . parse ( fs . readFileSync ( path . resolve ( __dirname , '../../../package.json' ) ) ) ;
10
11
12
+ const RETRY_STATUS_CODES = [ 502 , 503 , 504 ] ;
13
+ const retryOptions = {
14
+ fullResponse : true ,
15
+ maxAttempts : config . request . maxRetries ,
16
+ retryDelay : config . request . retryDelay ,
17
+ retryStrategy : ( err , response ) => ! isDebug ( ) && ( request . RetryStrategies . NetworkError ( err ) || RETRY_STATUS_CODES . includes ( response . statusCode ) ) ,
18
+ } ;
19
+
20
+ function _makeResponseError ( response ) {
21
+ return new Error ( JSON . stringify ( response . body || response ) ) ;
22
+ }
23
+
11
24
const sendHttpRequest = async ( httpOptions , authContext , throwOnUnauthorized , timeout = 30000 ) => {
12
25
let finalAuthContext ;
13
26
if ( ! authContext ) {
@@ -20,6 +33,7 @@ const sendHttpRequest = async (httpOptions, authContext, throwOnUnauthorized, ti
20
33
const finalOptions = _ . merge (
21
34
httpOptions ,
22
35
finalAuthContext . prepareHttpOptions ( ) ,
36
+ retryOptions ,
23
37
{
24
38
json : true ,
25
39
timeout,
@@ -30,45 +44,55 @@ const sendHttpRequest = async (httpOptions, authContext, throwOnUnauthorized, ti
30
44
} ,
31
45
) ;
32
46
debug ( 'Sending http request:\n%O' , finalOptions ) ;
33
- let response ;
34
- try {
35
- response = await rp ( finalOptions ) ;
36
- } catch ( err ) {
37
- debug ( 'Response:\n%O' , err . response . body ) ;
38
47
39
- if ( _ . isEqual ( err . statusCode , 401 ) ) {
40
- const error = new CFError ( {
41
- cause : err ,
42
- message : 'Error: Please create or update your authentication context' ,
43
- } ) ;
48
+ // only network errors will be thrown -- no need to catch
49
+ const response = await request ( finalOptions ) ;
44
50
45
- if ( ! throwOnUnauthorized ) {
46
- printError ( error ) ;
47
- process . exit ( 1 ) ;
48
- } else {
49
- throw error ;
50
- }
51
- }
52
- if ( _ . isEqual ( err . statusCode , 403 ) ) {
53
- printError ( new CFError ( {
54
- cause : err ,
55
- message : 'Error: You do not have permissions to perform this action' ,
56
- } ) ) ;
51
+ debug ( 'Response:\n%O' , response . body ) ;
52
+
53
+ const { statusCode } = response ;
54
+
55
+ // if for some reason request was not properly redirected (when "Location" header is lost, not usual case)
56
+ if ( statusCode >= 300 && statusCode < 400 ) {
57
+ throw new CFError ( {
58
+ cause : _makeResponseError ( response ) ,
59
+ message : 'Error: Request was not properly redirected' ,
60
+ } ) ;
61
+ }
62
+ if ( statusCode === 401 ) {
63
+ const error = new CFError ( {
64
+ cause : _makeResponseError ( response ) ,
65
+ message : 'Error: Please create or update your authentication context' ,
66
+ } ) ;
67
+
68
+ if ( ! throwOnUnauthorized ) {
69
+ printError ( error ) ;
57
70
process . exit ( 1 ) ;
71
+ } else {
72
+ throw error ;
58
73
}
74
+ }
75
+ if ( statusCode === 403 ) {
76
+ printError ( new CFError ( {
77
+ cause : _makeResponseError ( response ) ,
78
+ message : 'Error: You do not have permissions to perform this action' ,
79
+ } ) ) ;
80
+ process . exit ( 1 ) ;
81
+ }
59
82
60
- if ( _ . get ( err , 'error.message' ) ) {
61
- if ( _ . get ( err , 'error.error' ) ) {
62
- throw new Error ( `message: ${ err . error . message } \nerror: ${ err . error . error } ` ) ;
83
+ // other status codes
84
+ if ( statusCode >= 400 && statusCode < 600 ) {
85
+ if ( _ . get ( response , 'body.message' ) ) {
86
+ if ( _ . get ( response , 'body.error' ) ) {
87
+ throw new Error ( `message: ${ response . body . message } \nerror: ${ response . body . error } ` ) ;
63
88
} else {
64
- throw new Error ( err . error . message ) ;
89
+ throw new Error ( response . body . message ) ;
65
90
}
66
91
} else {
67
- throw err ;
92
+ throw _makeResponseError ( response ) ;
68
93
}
69
94
}
70
- debug ( 'Response:\n%O' , response ) ;
71
- return response ;
95
+ return response . body ;
72
96
} ;
73
97
74
98
module . exports = {
0 commit comments