How to report errors while parsing content in ES6 tagged templates?

48 Views Asked by At

I'm working with a friend on a small Javascript experiment, which involves a basic HTML parser, implemented as a simple state machine - you can see the code here.

My question is regarding tagged template functions which involve any kind of parser, with regards to error reporting - that is, if the parser detects an invalid state, it needs to report where the error was found in the input.

My problem is tracking and/or explaining where the error was found, in a way that makes sense.

The input to a tagged template function is actually bits of source (in my case HTML) alternating with Javascript values, so you can't simply (as I'm doing now, as you would do in most normal parsers) count characters and report the position, since the alternating Javascript values may not be strings, or may be strings that don't get parsed as literal source.

Is there any way for tagged template functions to discover the source file locations of the alternating input strings/values?

Or am I right in suspecting that a run-time facility of this sort is virtually impossible? Is there literally no useful way to implement this, short of using a Javascript parser, possibly ahead-of-time, to discover and log the source locations?

1

There are 1 best solutions below

1
On

All that can be done here is to output the expected context where the problem took place. Considering that the problem was caused by three:

const three = null;
`one${two}${three}four`

Tag function arguments can be concatenated in error message to the point where they start to make sense, e.g.

Expected a number as an expression at position 2, got `null`,
`one${...}${...}four`
            ^^^

Stack trace can also be retrieved if needed with new Error().stack.

If more precision is required, a template engine should be used instead of template literals because all necessary data is available during template compilation.

The options for tag function are same as for any other function. If foo function was called with bar variable as an argument that equals 1 (like foo(bar)), it may be impossible to figure out that it was called with bar from inside foo, because all we've got is 1 value. The fact that it was called like foo(bar) can only be found out if we have stack trace and the access to source file - which we don't have under normal circumstances. This method can be used in cases where feedback should be provided on the context, e.g. a test runner - because it is responsible for script loading and has access to source files.