@@ -1234,13 +1234,22 @@ var jsonata = (function() {
12341234 }
12351235 }
12361236 // apply the procedure
1237+ var procName = expr . procedure . type === 'path' ? expr . procedure . steps [ 0 ] . value : expr . procedure . value ;
12371238 try {
1239+ if ( typeof proc === 'object' ) {
1240+ proc . token = procName ;
1241+ proc . position = expr . position ;
1242+ }
12381243 result = yield * apply ( proc , evaluatedArgs , input , environment ) ;
12391244 } catch ( err ) {
1240- // add the position field to the error
1241- err . position = expr . position ;
1242- // and the function identifier
1243- err . token = expr . procedure . type === 'path' ? expr . procedure . steps [ 0 ] . value : expr . procedure . value ;
1245+ if ( ! err . position ) {
1246+ // add the position field to the error
1247+ err . position = expr . position ;
1248+ }
1249+ if ( ! err . token ) {
1250+ // and the function identifier
1251+ err . token = procName ;
1252+ }
12441253 throw err ;
12451254 }
12461255 return result ;
@@ -1262,6 +1271,10 @@ var jsonata = (function() {
12621271 // the function returned a tail-call thunk
12631272 // unpack it, evaluate its arguments, and apply the tail call
12641273 var next = yield * evaluate ( result . body . procedure , result . input , result . environment ) ;
1274+ if ( result . body . procedure . type === 'variable' ) {
1275+ next . token = result . body . procedure . value ;
1276+ }
1277+ next . position = result . body . procedure . position ;
12651278 var evaluatedArgs = [ ] ;
12661279 for ( var ii = 0 ; ii < result . body . arguments . length ; ii ++ ) {
12671280 evaluatedArgs . push ( yield * evaluate ( result . body . arguments [ ii ] , result . input , result . environment ) ) ;
@@ -1282,40 +1295,50 @@ var jsonata = (function() {
12821295 */
12831296 function * applyInner ( proc , args , input , environment ) {
12841297 var result ;
1285- var validatedArgs = args ;
1286- if ( proc ) {
1287- validatedArgs = validateArguments ( proc . signature , args , input ) ;
1288- }
1298+ try {
1299+ var validatedArgs = args ;
1300+ if ( proc ) {
1301+ validatedArgs = validateArguments ( proc . signature , args , input ) ;
1302+ }
12891303
1290- if ( isLambda ( proc ) ) {
1291- result = yield * applyProcedure ( proc , validatedArgs ) ;
1292- } else if ( proc && proc . _jsonata_function === true ) {
1293- var focus = {
1294- environment : environment ,
1295- input : input
1296- } ;
1297- // the `focus` is passed in as the `this` for the invoked function
1298- result = proc . implementation . apply ( focus , validatedArgs ) ;
1299- // `proc.implementation` might be a generator function
1300- // and `result` might be a generator - if so, yield
1301- if ( isIterable ( result ) ) {
1302- result = yield * result ;
1304+ if ( isLambda ( proc ) ) {
1305+ result = yield * applyProcedure ( proc , validatedArgs ) ;
1306+ } else if ( proc && proc . _jsonata_function === true ) {
1307+ var focus = {
1308+ environment : environment ,
1309+ input : input
1310+ } ;
1311+ // the `focus` is passed in as the `this` for the invoked function
1312+ result = proc . implementation . apply ( focus , validatedArgs ) ;
1313+ // `proc.implementation` might be a generator function
1314+ // and `result` might be a generator - if so, yield
1315+ if ( isIterable ( result ) ) {
1316+ result = yield * result ;
1317+ }
1318+ } else if ( typeof proc === 'function' ) {
1319+ // typically these are functions that are returned by the invocation of plugin functions
1320+ // the `input` is being passed in as the `this` for the invoked function
1321+ // this is so that functions that return objects containing functions can chain
1322+ // e.g. $func().next().next()
1323+ result = proc . apply ( input , validatedArgs ) ;
1324+ /* istanbul ignore next */
1325+ if ( isIterable ( result ) ) {
1326+ result = yield * result ;
1327+ }
1328+ } else {
1329+ throw {
1330+ code : "T1006" ,
1331+ stack : ( new Error ( ) ) . stack
1332+ } ;
13031333 }
1304- } else if ( typeof proc === 'function' ) {
1305- // typically these are functions that are returned by the invocation of plugin functions
1306- // the `input` is being passed in as the `this` for the invoked function
1307- // this is so that functions that return objects containing functions can chain
1308- // e.g. $func().next().next()
1309- result = proc . apply ( input , validatedArgs ) ;
1310- /* istanbul ignore next */
1311- if ( isIterable ( result ) ) {
1312- result = yield * result ;
1334+ } catch ( err ) {
1335+ if ( proc ) {
1336+ if ( typeof err . token == 'undefined' && typeof proc . token !== 'undefined' ) {
1337+ err . token = proc . token ;
1338+ }
1339+ err . position = proc . position ;
13131340 }
1314- } else {
1315- throw {
1316- code : "T1006" ,
1317- stack : ( new Error ( ) ) . stack
1318- } ;
1341+ throw err ;
13191342 }
13201343 return result ;
13211344 }
0 commit comments