Skip to content

Commit b03ddf7

Browse files
SNOW-1926267: Fix promise rejecting for file upload errors (#1008)
Co-authored-by: Przemyslaw Motacki <przemyslaw.motacki@snowflake.com>
1 parent 556e783 commit b03ddf7

File tree

4 files changed

+68
-25
lines changed

4 files changed

+68
-25
lines changed

lib/connection/result/row_stream.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function RowStream(statement, context, options) {
6565
} else if (context.isFetchingResult) {
6666
// if we're still fetching the result, wait for the operation to complete
6767
context.on('statement-complete', init);
68-
} else if (context.result || isStatementErrorFatal(context.resultError)) {
68+
} else if (context.result || isStatementErrorFatal(context)) {
6969
// if we have a result or a fatal error, call init() in the next tick of
7070
// the event loop
7171
process.nextTick(init);
@@ -295,12 +295,16 @@ Util.inherits(RowStream, Readable);
295295
/**
296296
* Determines if a statement error is fatal.
297297
*
298-
* @param {Error} error
299-
*
300298
* @returns {Boolean}
299+
* @param context
301300
*/
302-
function isStatementErrorFatal(error) {
303-
return Errors.isOperationFailedError(error) && error.sqlState;
301+
function isStatementErrorFatal(context) {
302+
const error = context.resultError;
303+
return (Errors.isOperationFailedError(error) && error.sqlState) || isFileUploadError(error, context.type);
304+
}
305+
306+
function isFileUploadError(error, contextType) {
307+
return error && contextType === 'FILE_PRE_EXEC';
304308
}
305309

306310
/**

lib/connection/statement.js

+32-20
Original file line numberDiff line numberDiff line change
@@ -813,26 +813,7 @@ function FileStatementPreExec(
813813
* @param {Object} body
814814
*/
815815
context.onStatementRequestSucc = async function (body) {
816-
context.fileMetadata = body;
817-
818-
const fta = new FileTransferAgent(context);
819-
await fta.execute();
820-
821-
// build a result from the response
822-
const result = fta.result();
823-
824-
// init result and meta
825-
body.data.rowset = result.rowset;
826-
body.data.returned = body.data.rowset.length;
827-
body.data.rowtype = result.rowtype;
828-
body.data.parameters = [];
829-
830-
context.result = new Result({
831-
response: body,
832-
statement: this,
833-
services: context.services,
834-
connectionConfig: context.connectionConfig
835-
});
816+
await executeFileTransferRequest(context, body, this);
836817
};
837818

838819
/**
@@ -858,6 +839,37 @@ function FileStatementPreExec(
858839
sendRequestPreExec(context, context.onStatementRequestComp);
859840
}
860841

842+
async function executeFileTransferRequest(context, body, statement, fileTransferAgent) {
843+
context.fileMetadata = body;
844+
845+
const fta = fileTransferAgent ?? new FileTransferAgent(context);
846+
await fta.execute();
847+
848+
try {
849+
// build a result from the response
850+
const result = fta.result();
851+
852+
// init result and meta
853+
body.data = {
854+
rowset: result.rowset,
855+
returned: result.rowset.length,
856+
rowtype: result.rowtype,
857+
parameters: [],
858+
};
859+
860+
context.result = new Result({
861+
response: body,
862+
statement: statement,
863+
services: context.services,
864+
connectionConfig: context.connectionConfig
865+
});
866+
} catch (error) {
867+
context.resultError = error;
868+
}
869+
}
870+
871+
exports.executeFileTransferRequest = executeFileTransferRequest;
872+
861873
Util.inherits(FileStatementPreExec, BaseStatement);
862874

863875
/**

lib/file_transfer_agent/file_transfer_agent.js

+10
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,13 @@ function FileTransferAgent(context) {
213213

214214
if (results) {
215215
for (const meta of results) {
216+
if (meta['resultStatus'] === 'ERROR') {
217+
errorDetails = meta['errorDetails'];
218+
if (!errorDetails) {
219+
errorDetails = `Unknown error during PUT of file: ${meta['srcFilePath']}`;
220+
}
221+
throw new Error(errorDetails);
222+
}
216223
if (meta['srcCompressionType']) {
217224
srcCompressionType = meta['srcCompressionType']['name'];
218225
} else {
@@ -334,6 +341,9 @@ function FileTransferAgent(context) {
334341
continue;
335342
}
336343
results.push(result);
344+
if (result['resultStatus'] === resultStatus.ERROR) {
345+
break;
346+
}
337347
index += 1;
338348
if (INJECT_WAIT_IN_PUT > 0) {
339349
await new Promise(resolve => setTimeout(resolve, INJECT_WAIT_IN_PUT));

test/unit/connection/statement_test.js

+17
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,20 @@ describe('Statement.fetchResult()', function () {
411411
it(testCase.name, createItCallback(testCase));
412412
}
413413
});
414+
415+
it('Statement file transfer error', async function () {
416+
const mockFta = {
417+
execute: async function () {
418+
return null;
419+
},
420+
result: function () {
421+
throw new Error('some file transfer error');
422+
}
423+
};
424+
const context = {};
425+
const body = {
426+
'data': {},
427+
};
428+
await Statement.executeFileTransferRequest(context, body, null, mockFta);
429+
assert.strictEqual(context.resultError.message, 'some file transfer error');
430+
});

0 commit comments

Comments
 (0)