@@ -2,12 +2,82 @@ import { RequestOptions } from "@continuedev/config-types";
2
2
import * as followRedirects from "follow-redirects" ;
3
3
import { HttpProxyAgent } from "http-proxy-agent" ;
4
4
import { HttpsProxyAgent } from "https-proxy-agent" ;
5
- import fetch , { RequestInit , Response } from "node-fetch" ;
5
+ import fetch , { BodyInit , RequestInit , Response } from "node-fetch" ;
6
6
import { getAgentOptions } from "./getAgentOptions.js" ;
7
7
import { getProxyFromEnv , shouldBypassProxy } from "./util.js" ;
8
8
9
9
const { http, https } = ( followRedirects as any ) . default ;
10
10
11
+ function logRequest (
12
+ method : string ,
13
+ url : URL ,
14
+ headers : { [ key : string ] : string } ,
15
+ body : BodyInit | null | undefined ,
16
+ proxy ?: string ,
17
+ shouldBypass ?: boolean ,
18
+ ) {
19
+ console . log ( "=== FETCH REQUEST ===" ) ;
20
+ console . log ( `Method: ${ method } ` ) ;
21
+ console . log ( `URL: ${ url . toString ( ) } ` ) ;
22
+
23
+ // Log headers in curl format
24
+ console . log ( "Headers:" ) ;
25
+ for ( const [ key , value ] of Object . entries ( headers ) ) {
26
+ console . log ( ` -H '${ key } : ${ value } '` ) ;
27
+ }
28
+
29
+ // Log proxy information
30
+ if ( proxy && ! shouldBypass ) {
31
+ console . log ( `Proxy: ${ proxy } ` ) ;
32
+ }
33
+
34
+ // Log body
35
+ if ( body ) {
36
+ console . log ( `Body: ${ body } ` ) ;
37
+ }
38
+
39
+ // Generate equivalent curl command
40
+ let curlCommand = `curl -X ${ method } ` ;
41
+ for ( const [ key , value ] of Object . entries ( headers ) ) {
42
+ curlCommand += ` -H '${ key } : ${ value } '` ;
43
+ }
44
+ if ( body ) {
45
+ curlCommand += ` -d '${ body } '` ;
46
+ }
47
+ if ( proxy && ! shouldBypass ) {
48
+ curlCommand += ` --proxy '${ proxy } '` ;
49
+ }
50
+ curlCommand += ` '${ url . toString ( ) } '` ;
51
+ console . log ( `Equivalent curl: ${ curlCommand } ` ) ;
52
+ console . log ( "=====================" ) ;
53
+ }
54
+
55
+ async function logResponse ( resp : Response ) {
56
+ console . log ( "=== FETCH RESPONSE ===" ) ;
57
+ console . log ( `Status: ${ resp . status } ${ resp . statusText } ` ) ;
58
+ console . log ( "Response Headers:" ) ;
59
+ resp . headers . forEach ( ( value , key ) => {
60
+ console . log ( ` ${ key } : ${ value } ` ) ;
61
+ } ) ;
62
+
63
+ // TODO: For streamed responses, this caused the response to be consumed and the connection would just hang open
64
+ // Clone response to read body without consuming it
65
+ // const respClone = resp.clone();
66
+ // try {
67
+ // const responseText = await respClone.text();
68
+ // console.log(`Response Body: ${responseText}`);
69
+ // } catch (e) {
70
+ // console.log("Could not read response body:", e);
71
+ // }
72
+ console . log ( "======================" ) ;
73
+ }
74
+
75
+ function logError ( error : unknown ) {
76
+ console . log ( "=== FETCH ERROR ===" ) ;
77
+ console . log ( `Error: ${ error } ` ) ;
78
+ console . log ( "===================" ) ;
79
+ }
80
+
11
81
export async function fetchwithRequestOptions (
12
82
url_ : URL | string ,
13
83
init ?: RequestInit ,
@@ -68,15 +138,28 @@ export async function fetchwithRequestOptions(
68
138
console . log ( "Unable to parse HTTP request body: " , e ) ;
69
139
}
70
140
141
+ const finalBody = updatedBody ?? init ?. body ;
142
+ const method = init ?. method || "GET" ;
143
+
144
+ // Verbose logging for debugging - log request details
145
+ if ( process . env . VERBOSE_FETCH ) {
146
+ logRequest ( method , url , headers , finalBody , proxy , shouldBypass ) ;
147
+ }
148
+
71
149
// fetch the request with the provided options
72
150
try {
73
151
const resp = await fetch ( url , {
74
152
...init ,
75
- body : updatedBody ?? init ?. body ,
153
+ body : finalBody ,
76
154
headers : headers ,
77
155
agent : agent ,
78
156
} ) ;
79
157
158
+ // Verbose logging for debugging - log response details
159
+ if ( process . env . VERBOSE_FETCH ) {
160
+ await logResponse ( resp ) ;
161
+ }
162
+
80
163
if ( ! resp . ok ) {
81
164
const requestId = resp . headers . get ( "x-request-id" ) ;
82
165
if ( requestId ) {
@@ -86,6 +169,11 @@ export async function fetchwithRequestOptions(
86
169
87
170
return resp ;
88
171
} catch ( error ) {
172
+ // Verbose logging for errors
173
+ if ( process . env . VERBOSE_FETCH ) {
174
+ logError ( error ) ;
175
+ }
176
+
89
177
if ( error instanceof Error && error . name === "AbortError" ) {
90
178
// Return a Response object that streamResponse etc can handle
91
179
return new Response ( null , {
0 commit comments