majintao0131 / yaml-cpp

Automatically exported from code.google.com/p/yaml-cpp
MIT License
0 stars 0 forks source link

More detailed exception messages #33

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
It would be nice if there were more information in the exception messages.
 For example, instead of "key not found", something like:
key [key_name] not found

If you know the path to the node, it could even be:
key [key_name] not found in node [a.b.c.e]

Original issue reported on code.google.com by josh.faust@gmail.com on 21 Aug 2009 at 2:09

GoogleCodeExporter commented 9 years ago
I'm not a huge fan of this idea, for two reasons:

1. YAML keys can be arbitrary data (not just strings), and yaml-cpp allows 
lookup
indexed by any type that overloads `operator >>`. What would we output if you 
lookup
with a type that's not streamable?

2. Even if we only output the key when it's a string, what happens if it has a
newline? or unprintable characters? or is *very* long? I agree that it'd be 
nice to
see the key sometimes, but I don't want the error message to get out of hand 
(and
become unreadable).

As for the path to the node (assuming I'm interpreting you right), there are two
problems:

1. Since keys can be arbitrary, the node in question might be part of a key, not
value. How would you illustrate this?

2. We don't currently store any such "meta-data" in a node (other than the file
marker) - it's effectively an independent YAML document.

However, if you can think of a good solution that avoids (or minimizes) these
problems, I'd be happy to hear it!

Original comment by jbe...@gmail.com on 22 Aug 2009 at 12:06

GoogleCodeExporter commented 9 years ago
I suppose in general I would output the key as yaml.  If it has newlines, or is 
very
long, that's fine by me -- having enough information to fix the problem is far
preferrable to not having any information at all (other than that a key 
somewhere was
not found).  The solution right now is to try/catch around each map lookup, and
rethrow -- necessary anyway if some of your fields are optional, but cumbersome 
if
you have a bunch of fields that are required.

I can wrap my usage of it very easily, so this isn't really a big deal or 
anything.

Path to the node is not as useful as the key itself, so I suppose I wouldn't 
worry
about it.

Original comment by josh.faust@gmail.com on 22 Aug 2009 at 1:41

GoogleCodeExporter commented 9 years ago
It's not always possible to output the key as YAML. Remember, the type of syntax
we're dealing with here looks like:

    MyCrazyObj obj = Foo(bar);
    node[obj] >> value;

Then yaml-cpp goes through all the keys in 'node' and tries

    MyCrazyObj other;
    key >> other;

and checks if `other == obj`. If it gets a match, it returns the `YAML::Node` 
and
then we extract 'value'. If not, then it throws, saying that it couldn't find 
the key
'obj' of type MyCrazyObj.

The only prerequisite here is that `operator >> (const YAML::Node&, 
MyCrazyObj&)`
exists. So how can we output 'obj' as YAML? We would need to require that 
`operator
<< (YAML::Emitter&, const MyCrazyObj&)` exists also, or something like that, 
and if
you're just parsing, you probably don't want to be bothered writing emitter 
overloads.

The point is, when we don't find a key, the missing key is some opaque data 
type, not
YAML.

In any case, if you're just worried about optional fields, yaml-cpp provides
`Node::FindValue`, which returns a `const Node *`, and NULL if the key doesn't 
exist.
I just noticed that I didn't update the wiki with this information, so I did so 
now.
Check out [HowToParseADocument#Optional_Keys].

By the way, I'm not trying to be obtuse here - I've had my share of, "Key not 
found?
WHICH key not found???" :)

I'm tempted to specialize the error message just for strings, but I'm not 100%
convinced yet.

Original comment by jbe...@gmail.com on 22 Aug 2009 at 2:33

GoogleCodeExporter commented 9 years ago
Ah, interesting, I didn't think about the fact that if you fail to find the key 
you
really have no idea what type of object it is.  That does make things hard :(.  
Is
there any reason you didn't do it the other way, ie. have MyCrazyObj define a >>
operator into YAML::Node if it's going to be a key?  That way every key is 
guaranteed
to be yaml, which means you'd be able to print it out.

In my case I don't actually want optional keys (I had seen them from looking at 
the
source, but thanks for updating the wiki :)), I just want to be able to have a 
single
try/catch around a block of 5 or so key lookups because they're all required, 
and it
would be nice to tell the user what key is missing if something fails.  Again, 
in my
case this is trivial to wrap to show the key value because the key is always a
string, but I'm fairly new to yaml so I'm not used to the fact that random 
other yaml
expressions can also be keys.

I could go either way on specializing for strings -- it's nice because I 
imagine most
maps are actually keyed on strings, but not nice because you get different 
behavior
based on your key type.  Specializing for all the primitive types would be an 
option,
but it may not be worth the complexity.

Original comment by josh.faust@gmail.com on 22 Aug 2009 at 7:57

GoogleCodeExporter commented 9 years ago
In r324, keys that are strings or numeric types are outputted in the key not 
found
exception. I'd still like some formatting for the strings if there's a newline, 
but
for now it's pretty useful, I think.

Original comment by jbe...@gmail.com on 12 Nov 2009 at 5:02

GoogleCodeExporter commented 9 years ago
Excellent, thanks.

Original comment by josh.faust@gmail.com on 12 Nov 2009 at 9:01