Skip to content

Commit 48eff4a

Browse files
committed
fix: handle exceptions in transforms properly in streaming APIs
1 parent 854df7f commit 48eff4a

File tree

8 files changed

+148
-11
lines changed

8 files changed

+148
-11
lines changed

build.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const replaceDependenciesByJsdelivr = {
2727
});
2828

2929
const dependencies = {
30-
'@streamparser/json': 'https://cdn.jsdelivr.net/npm/@streamparser/[email protected].8/dist/mjs/index.mjs',
30+
'@streamparser/json': 'https://cdn.jsdelivr.net/npm/@streamparser/[email protected].9/dist/mjs/index.mjs',
3131
'lodash.get': 'https://cdn.jsdelivr.net/gh/lodash/lodash@master/get.js'
3232
};
3333

dist/cdn/plainjs/StreamParser.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// packages/plainjs/src/StreamParser.js
2-
import { Tokenizer, TokenParser, TokenType } from "https://cdn.jsdelivr.net/npm/@streamparser/[email protected].8/dist/mjs/index.mjs";
2+
import { Tokenizer, TokenParser, TokenType } from "https://cdn.jsdelivr.net/npm/@streamparser/[email protected].9/dist/mjs/index.mjs";
33
import JSON2CSVBase from "./BaseParser.js";
44
var JSON2CSVStreamParser = class extends JSON2CSVBase {
55
constructor(opts, asyncOpts) {

package-lock.json

+16-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/node/test/AsyncParser.js

+34
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os from 'os';
2+
import { Writable } from 'stream';
23

34
import TestRunner from '@json2csv/test-helpers/TestRunner.js';
45
import { forceLfEol } from '@json2csv/test-helpers/utils.js';
@@ -890,6 +891,39 @@ export default function (jsonFixtures, csvFixtures) {
890891
t.equal(csv, csvFixtures.defaultCustomTransform);
891892
});
892893

894+
testRunner.add('should handle errors in transforms correctly', async (t) => {
895+
const outputStream = new Writable({
896+
write(chunk, encoding, callback) {
897+
callback();
898+
},
899+
});
900+
901+
const opts = {
902+
transforms: [
903+
(row) => {
904+
if (row.carModel === 'Mercedes') {
905+
throw new Error('Mercerdes not allowed');
906+
}
907+
908+
return row;
909+
},
910+
],
911+
};
912+
913+
const parser = new Parser(opts);
914+
const transformation = parser.parse(jsonFixtures.default());
915+
const promise = new Promise((res) => {
916+
transformation.on('end', () => {
917+
t.fail('Exception expected');
918+
res();
919+
});
920+
transformation.on('error', (err) => res(err));
921+
});
922+
923+
transformation.pipe(outputStream);
924+
await promise;
925+
});
926+
893927
// Formatters
894928

895929
// Number

packages/node/test/AsyncParserInMemory.js

+34
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os from 'os';
2+
import { Writable } from 'stream';
23

34
import TestRunner from '@json2csv/test-helpers/TestRunner.js';
45
import { forceLfEol } from '@json2csv/test-helpers/utils.js';
@@ -890,6 +891,39 @@ export default function (jsonFixtures, csvFixtures) {
890891
t.equal(csv, csvFixtures.defaultCustomTransform);
891892
});
892893

894+
testRunner.add('should handle errors in transforms correctly', async (t) => {
895+
const outputStream = new Writable({
896+
write(chunk, encoding, callback) {
897+
callback();
898+
},
899+
});
900+
901+
const opts = {
902+
transforms: [
903+
(row) => {
904+
if (row.carModel === 'Mercedes') {
905+
throw new Error('Mercerdes not allowed');
906+
}
907+
908+
return row;
909+
},
910+
],
911+
};
912+
913+
const parser = new Parser(opts);
914+
const transformation = parser.parse(jsonFixtures.default());
915+
const promise = new Promise((res) => {
916+
transformation.on('end', () => {
917+
t.fail('Exception expected');
918+
res();
919+
});
920+
transformation.on('error', (err) => res(err));
921+
});
922+
923+
transformation.pipe(outputStream);
924+
await promise;
925+
});
926+
893927
// Formatters
894928

895929
// Number

packages/node/test/Transform.js

+34
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os from 'os';
2+
import { Writable } from 'stream';
23

34
import TestRunner from '@json2csv/test-helpers/TestRunner.js';
45
import { forceLfEol } from '@json2csv/test-helpers/utils.js';
@@ -885,6 +886,39 @@ export default function (jsonFixtures, csvFixtures) {
885886
t.equal(csv, csvFixtures.defaultCustomTransform);
886887
});
887888

889+
testRunner.add('should handle errors in transforms correctly', async (t) => {
890+
const outputStream = new Writable({
891+
write(chunk, encoding, callback) {
892+
callback();
893+
},
894+
});
895+
896+
const opts = {
897+
transforms: [
898+
(row) => {
899+
if (row.carModel === 'Mercedes') {
900+
throw new Error('Mercerdes not allowed');
901+
}
902+
903+
return row;
904+
},
905+
],
906+
};
907+
908+
const parser = new Parser(opts);
909+
const transformation = jsonFixtures.default().pipe(parser);
910+
const promise = new Promise((res) => {
911+
transformation.on('end', () => {
912+
t.fail('Exception expected');
913+
res();
914+
});
915+
transformation.on('error', (err) => res(err));
916+
});
917+
918+
transformation.pipe(outputStream);
919+
await promise;
920+
});
921+
888922
// Formatters
889923

890924
// Number

packages/plainjs/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
},
3939
"dependencies": {
4040
"@json2csv/formatters": "^6.0.0-alpha.4",
41-
"@streamparser/json": "^0.0.8",
41+
"@streamparser/json": "^0.0.9",
4242
"lodash.get": "^4.4.2"
4343
}
4444
}

packages/plainjs/test/StreamParser.js

+27
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,33 @@ export default function (jsonFixtures, csvFixtures) {
857857
t.equal(csv, csvFixtures.defaultCustomTransform);
858858
});
859859

860+
testRunner.add('should handle errors in transforms correctly', async (t) => {
861+
const opts = {
862+
transforms: [
863+
(row) => {
864+
if (row.carModel === 'Mercedes') {
865+
throw new Error('Mercerdes not allowed');
866+
}
867+
868+
return row;
869+
},
870+
],
871+
};
872+
873+
const parser = new Parser(opts);
874+
875+
const promise = new Promise((res) => {
876+
parser.onEnd = () => {
877+
t.fail('Exception expected');
878+
res();
879+
};
880+
parser.onError = (err) => res(err);
881+
});
882+
883+
parser.write('{ "carModel": "Mercedes" }');
884+
await promise;
885+
});
886+
860887
// Formatters
861888

862889
// Number

0 commit comments

Comments
 (0)