Skip to content
This repository has been archived by the owner on Jun 28, 2021. It is now read-only.

Commit

Permalink
cast: catch error in user functions
Browse files Browse the repository at this point in the history
  • Loading branch information
wdavidw committed Nov 12, 2018
1 parent 406723c commit a0ca48b
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -29,6 +29,7 @@ New features:
* delimiter: may be a Buffer
* delimiter: handle multiple bytes/characters
* callback: export info object as third argument
* cast: catch error in user functions

API management

Expand Down
67 changes: 46 additions & 21 deletions lib/es5/index.js
Expand Up @@ -2,6 +2,14 @@

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
Expand Down Expand Up @@ -435,11 +443,13 @@ function (_Transform) {

continue;
} else {
this.__onField();
var errField = this.__onField();

if (errField !== undefined) return errField;

var _err2 = this.__onRow();
var errRecord = this.__onRow();

if (_err2 !== undefined) return _err2;
if (errRecord !== undefined) return errRecord;
}

if (to !== -1 && this.info.records >= to) {
Expand Down Expand Up @@ -468,8 +478,9 @@ function (_Transform) {
var delimiterLength = this.__isDelimiter(chr, buf, pos);

if (delimiterLength !== 0) {
this.__onField();
var _errField = this.__onField();

if (_errField !== undefined) return _errField;
pos += delimiterLength - 1;
continue;
}
Expand All @@ -478,9 +489,9 @@ function (_Transform) {

if (commenting === false && max_record_size !== 0) {
if (this.state.record_length + this.state.field.length > max_record_size) {
var _err3 = this.__error("Max Record Size: record exceed the maximum number of tolerated bytes of ".concat(max_record_size, " on line ").concat(this.info.lines));
var _err2 = this.__error("Max Record Size: record exceed the maximum number of tolerated bytes of ".concat(max_record_size, " on line ").concat(this.info.lines));

if (_err3 !== undefined) return _err3;
if (_err2 !== undefined) return _err2;
}
}

Expand All @@ -491,9 +502,9 @@ function (_Transform) {
if (lappend === true && rappend === true) {
this.state.field.append(chr);
} else if (rtrim === true && !this.__isCharTrimable(chr)) {
var _err4 = this.__error("Invalid Closing Quote: found non trimable byte after quote at line ".concat(this.info.lines));
var _err3 = this.__error("Invalid Closing Quote: found non trimable byte after quote at line ".concat(this.info.lines));

if (_err4 !== undefined) return _err4;
if (_err3 !== undefined) return _err3;
}
}

Expand All @@ -504,17 +515,21 @@ function (_Transform) {

if (end === true) {
if (this.state.quoting === true) {
var _err5 = this.__error("Invalid Closing Quote: quote is not closed at line ".concat(this.info.lines));
var _err4 = this.__error("Invalid Closing Quote: quote is not closed at line ".concat(this.info.lines));

if (_err5 !== undefined) return _err5;
if (_err4 !== undefined) return _err4;
} else {
// Skip last line if it has no characters
if (this.state.record.length !== 0 || this.state.field.length !== 0) {
this.__onField();
var _errField2 = this.__onField();

if (_errField2 !== undefined) return _errField2;

var _err6 = this.__onRow();
var _errRecord = this.__onRow();

if (_err6 !== undefined) return _err6;
if (_errRecord !== undefined) return _errRecord;
} else if (this.state.wasRowDelimiter === true) {
this.info.empty_lines++;
}
}
} else {
Expand Down Expand Up @@ -558,9 +573,9 @@ function (_Transform) {

if (err !== undefined) return err;
} else {
var _err7 = this.__error("Invalid Record Length: header length is ".concat(columns.length, ", got ").concat(recordLength, " on line ").concat(this.info.lines));
var _err5 = this.__error("Invalid Record Length: header length is ".concat(columns.length, ", got ").concat(recordLength, " on line ").concat(this.info.lines));

if (_err7 !== undefined) return _err7;
if (_err5 !== undefined) return _err5;
}
}
}
Expand Down Expand Up @@ -684,7 +699,13 @@ function (_Transform) {
}

if (cast === true) {
field = this.__cast(field);
var _this$__cast = this.__cast(field),
_this$__cast2 = _slicedToArray(_this$__cast, 2),
err = _this$__cast2[0],
f = _this$__cast2[1];

if (err !== undefined) return err;
field = f;
}

this.state.record.push(field);
Expand Down Expand Up @@ -713,18 +734,22 @@ function (_Transform) {
};

if (this.state.castField !== null) {
return this.state.castField.call(null, field, context);
try {
return [undefined, this.state.castField.call(null, field, context)];
} catch (err) {
return [err];
}
}

if (this.__isInt(field) === true) {
return parseInt(field);
return [undefined, parseInt(field)];
} else if (this.__isFloat(field)) {
return parseFloat(field);
return [undefined, parseFloat(field)];
} else if (this.options.cast_date !== false) {
return this.options.cast_date.call(null, field, context);
return [undefined, this.options.cast_date.call(null, field, context)];
}

return field;
return [undefined, field];
}
}, {
key: "__isInt",
Expand Down
37 changes: 24 additions & 13 deletions lib/index.js
Expand Up @@ -321,9 +321,10 @@ class Parser extends Transform {
this.__resetRow()
continue
}else{
this.__onField()
const err = this.__onRow()
if(err !== undefined) return err
const errField = this.__onField()
if(errField !== undefined) return errField
const errRecord = this.__onRow()
if(errRecord !== undefined) return errRecord
}
if(to !== -1 && this.info.records >= to){
this.state.stop = true
Expand All @@ -345,7 +346,8 @@ class Parser extends Transform {
}
let delimiterLength = this.__isDelimiter(chr, buf, pos)
if(delimiterLength !== 0){
this.__onField()
const errField = this.__onField()
if(errField !== undefined) return errField
pos += delimiterLength - 1
continue
}
Expand Down Expand Up @@ -378,9 +380,12 @@ class Parser extends Transform {
}else{
// Skip last line if it has no characters
if(this.state.record.length !== 0 || this.state.field.length !== 0){
this.__onField()
const err = this.__onRow()
if(err !== undefined) return err
const errField = this.__onField()
if(errField !== undefined) return errField
const errRecord = this.__onRow()
if(errRecord !== undefined) return errRecord
}else if(this.state.wasRowDelimiter === true){
this.info.empty_lines++
}
}
}else{
Expand Down Expand Up @@ -495,7 +500,9 @@ class Parser extends Transform {
field = field.trimRight()
}
if(cast === true){
field = this.__cast(field)
const [err, f] = this.__cast(field)
if(err !== undefined) return err
field = f
}
this.state.record.push(field)
this.state.record_length += field.length
Expand All @@ -517,16 +524,20 @@ class Parser extends Transform {
skipped_lines: this.info.skipped_lines
}
if(this.state.castField !== null){
return this.state.castField.call(null, field, context)
try{
return [undefined, this.state.castField.call(null, field, context)]
}catch(err){
return [err]
}
}
if(this.__isInt(field) === true){
return parseInt(field)
return [undefined, parseInt(field)]
}else if(this.__isFloat(field)){
return parseFloat(field)
return [undefined, parseFloat(field)]
}else if(this.options.cast_date !== false){
return this.options.cast_date.call(null, field, context)
return [undefined, this.options.cast_date.call(null, field, context)]
}
return field
return [undefined, field]
}
__isInt(value){
return /^(\-|\+)?([1-9]+[0-9]*)$/.test(value)
Expand Down
2 changes: 1 addition & 1 deletion test/api.info.coffee
Expand Up @@ -4,7 +4,7 @@ parse = require '../lib'
describe 'API info', ->

it 'is exported in the callback', (next) ->
parser = parse '''
parse '''
1,2,3
a,b,c
''', (err, data, info) ->
Expand Down
12 changes: 12 additions & 0 deletions test/options.cast.coffee
Expand Up @@ -101,3 +101,15 @@ describe 'options "cast"', ->
{a: 4, b: 5, c: 6}
] unless err
next err

it 'catch error', (next) ->
parse """
1,2,3
4,5,6
""",
cast: (value, context) ->
if value is '6' then throw Error 'Catchme'
value
, (err, records) ->
err.message.should.eql 'Catchme'
next()
2 changes: 1 addition & 1 deletion test/options.columns.coffee
Expand Up @@ -25,7 +25,7 @@ describe 'options columns', ->
5,6,7,8
""", columns: ["a", false, "c", false], (err, data) ->
data.should.eql [
{ a: "1", c: "3"}
{ a: "1", c: "3" }
{ a: "5", c: "7" }
] unless err
next err
Expand Down

0 comments on commit a0ca48b

Please sign in to comment.