@@ -114,65 +114,8 @@ describe("export", () => {
114
114
] ) ;
115
115
const mockSqlContent = "PRAGMA defer_foreign_keys=TRUE;" ;
116
116
117
- msw . use (
118
- http . post (
119
- "*/accounts/:accountId/d1/database/:databaseId/export" ,
120
- async ( { request } ) => {
121
- // This endpoint is polled recursively. If we respond immediately,
122
- // the callstack builds up quickly leading to a hard-to-debug OOM error.
123
- // This timeout ensures that if the endpoint is accidently polled infinitely
124
- // the test will timeout before breaching available memory
125
- await setTimeout ( 10 ) ;
126
-
127
- const body = ( await request . json ( ) ) as Record < string , unknown > ;
128
-
129
- // First request, initiates a new task
130
- if ( ! body . current_bookmark ) {
131
- return HttpResponse . json (
132
- {
133
- success : true ,
134
- result : {
135
- success : true ,
136
- type : "export" ,
137
- at_bookmark : "yyyy" ,
138
- status : "active" ,
139
- messages : [
140
- "Generating xxxx-yyyy.sql" ,
141
- "Uploaded part 2" , // out-of-order uploads ok
142
- "Uploaded part 1" ,
143
- ] ,
144
- } ,
145
- } ,
146
- { status : 202 }
147
- ) ;
148
- }
149
- // Subsequent request, sees that it is complete
150
- else {
151
- return HttpResponse . json (
152
- {
153
- success : true ,
154
- result : {
155
- success : true ,
156
- type : "export" ,
157
- at_bookmark : "yyyy" ,
158
- status : "complete" ,
159
- result : {
160
- filename : "xxxx-yyyy.sql" ,
161
- signed_url : "https://example.com/xxxx-yyyy.sql" ,
162
- } ,
163
- messages : [
164
- "Uploaded part 3" ,
165
- "Uploaded part 4" ,
166
- "Finished uploading xxxx-yyyy.sql in 4 parts." ,
167
- ] ,
168
- } ,
169
- } ,
170
- { status : 200 }
171
- ) ;
172
- }
173
- }
174
- )
175
- ) ;
117
+ mockResponses ( ) ;
118
+
176
119
msw . use (
177
120
http . get ( "https://example.com/xxxx-yyyy.sql" , async ( ) => {
178
121
return HttpResponse . text ( mockSqlContent , { status : 200 } ) ;
@@ -182,4 +125,95 @@ describe("export", () => {
182
125
await runWrangler ( "d1 export db --remote --output test-remote.sql" ) ;
183
126
expect ( fs . readFileSync ( "test-remote.sql" , "utf8" ) ) . toBe ( mockSqlContent ) ;
184
127
} ) ;
128
+
129
+ it ( "should handle remote presigned URL errors" , async ( ) => {
130
+ setIsTTY ( false ) ;
131
+ writeWranglerConfig ( {
132
+ d1_databases : [
133
+ { binding : "DATABASE" , database_name : "db" , database_id : "xxxx" } ,
134
+ ] ,
135
+ } ) ;
136
+ mockGetMemberships ( [
137
+ { id : "IG-88" , account : { id : "1701" , name : "enterprise" } } ,
138
+ ] ) ;
139
+
140
+ mockResponses ( ) ;
141
+
142
+ msw . use (
143
+ http . get ( "https://example.com/xxxx-yyyy.sql" , async ( ) => {
144
+ return HttpResponse . text (
145
+ `<?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><Message>Access Denied</Message></Error>` ,
146
+ { status : 403 }
147
+ ) ;
148
+ } )
149
+ ) ;
150
+
151
+ await expect (
152
+ runWrangler ( "d1 export db --remote --output test-remote.sql" )
153
+ ) . rejects . toThrowError (
154
+ / T h e r e w a s a n e r r o r w h i l e d o w n l o a d i n g f r o m t h e p r e s i g n e d U R L w i t h s t a t u s c o d e : 4 0 3 /
155
+ ) ;
156
+ } ) ;
185
157
} ) ;
158
+
159
+ function mockResponses ( ) {
160
+ msw . use (
161
+ http . post (
162
+ "*/accounts/:accountId/d1/database/:databaseId/export" ,
163
+ async ( { request } ) => {
164
+ // This endpoint is polled recursively. If we respond immediately,
165
+ // the callstack builds up quickly leading to a hard-to-debug OOM error.
166
+ // This timeout ensures that if the endpoint is accidently polled infinitely
167
+ // the test will timeout before breaching available memory
168
+ await setTimeout ( 10 ) ;
169
+
170
+ const body = ( await request . json ( ) ) as Record < string , unknown > ;
171
+
172
+ // First request, initiates a new task
173
+ if ( ! body . current_bookmark ) {
174
+ return HttpResponse . json (
175
+ {
176
+ success : true ,
177
+ result : {
178
+ success : true ,
179
+ type : "export" ,
180
+ at_bookmark : "yyyy" ,
181
+ status : "active" ,
182
+ messages : [
183
+ "Generating xxxx-yyyy.sql" ,
184
+ "Uploaded part 2" , // out-of-order uploads ok
185
+ "Uploaded part 1" ,
186
+ ] ,
187
+ } ,
188
+ } ,
189
+ { status : 202 }
190
+ ) ;
191
+ }
192
+ // Subsequent request, sees that it is complete
193
+ else {
194
+ return HttpResponse . json (
195
+ {
196
+ success : true ,
197
+ result : {
198
+ success : true ,
199
+ type : "export" ,
200
+ at_bookmark : "yyyy" ,
201
+ status : "complete" ,
202
+ result : {
203
+ filename : "xxxx-yyyy.sql" ,
204
+ signed_url : "https://example.com/xxxx-yyyy.sql" ,
205
+ } ,
206
+ messages : [
207
+ "Uploaded part 3" ,
208
+ "Uploaded part 4" ,
209
+ "Finished uploading xxxx-yyyy.sql in 4 parts." ,
210
+ ] ,
211
+ } ,
212
+ } ,
213
+ { status : 200 }
214
+ ) ;
215
+ }
216
+ }
217
+ )
218
+ ) ;
219
+ }
0 commit comments