Version: next

Errors and labels

Error messages in Parsica give you information about what the parser expected, where the problem happened, and what it got instead.

<?php
$parser = sepBy1(char(','), atLeastOne(alphaChar()));
$input = "Ÿellow,Red,Green";
//$parser->tryString($input);

(Note: We're using UpToDocs to automatically test all the code samples in this documentation. The downside is that throwing an exception in the docs causes the build to fail! That's why some of the code above is commented out.)

If you uncomment and run the above code, you'll get an exception like this:

<input>:1:1
|
1 | Ÿellow,Red,Green
| ^— column 1
Unexpected 'Ÿ'
Expecting at least one A-Z or a-z, separated by ','

It shows the filename, line number and column position, as well as an autogenerated expectation.

Often you'll want something a bt more meaningful than "at least one A-Z or a-z". You can do that by attaching your own labels to some of your parsers. For example, we can label the colours:

<?php
$parser = sepBy1(
string(','),
atLeastOne(alphaChar())->label("colour")
);

That will yield:

...
Expecting colour, separated by ','

Or you can attach the label to the entire parser:

<?php
$parser = sepBy1(
string(','),
atLeastOne(alphaChar())
)->label("a list of colours");
...
Expecting a list of colours

The best approach will of course depend on your specific use case. A good habit is to keep in mind that ultimately, the errors are there for the end user who will see them. This could be a user who enters some values in a form, a programmer using your API, someone building other parsers on top of your parser... Feed your parser with some wrong inputs that you are likely to get in the real world, and get a feel for what makes a helpful error message.

Doing your own error reporting

The information in the error message is also available from ParseResult. You can use this to make your own error messages, if you want to render them as HTML or send them to an API. For example, these are the line and column number where the parser ended up:

<?php
$result = string('Hello')->run(new StringStream("Hello, World"));
assertSame(1, $result->position()->line());
assertSame(6, $result->position()->column());

Have a look at the ParseResult API to see what else it can do.