A library function parses a file and returns an object. If a parser encounters unknown data, missing values etc., it shouldn't throw an exception and stop parsing (because this is not fatal), but there should be a way to pass information about these things to a caller (so that warnings can be displayed in the UI, for example). How can these warning be returned? I'm thinking of passing a callback function/object into the library, are there any other possible solutions?
A common solution is to provide the warning(s) via a related function. That way the warning will only be read when the client code wants it.
Well the returned object could include the warnings. In webservices, I usually deal with wrapper classes pretty much like:
class Wrapper {
List<Warning> Warnings { get; set; }
bool HasWarnings { get { return Warnings != null && Warnings.Count > 0; } }
MyObject Result { get; set; }
}
This way it will be the responsibility of the receiving end to decide whether to take action on any warnings, but from its structure, it also becomes apparent to the person invoking the webservices that there might be warnings. A returned object like this pretty much begs for some basic level of error checking on the receiving side.
If your programming language supports it, I recommend using events to pass warnings. Your calling program can capture the event and then decide what to do with it based on the severity or type of warning that is passed with the event notification. With events, the user doesn't have to wait for the entire file to finish processing before they see if there are any errors. If you also provide a method to cancel the file processing they can make the decision to stop the processing if they decide the errors raised are serious enough.
In pseudocode:
class ParseResult (
Outcome <succesful, warnings, failed completely>,
ParseOutput <result>,
List<Warning> warnings
)
So you get back a nugget where you can quickly unwrap the end result, but also get status and warnings
I would have a collection of errors easily accessible on the parser, something like this:
public class Parser
{
public bool HasErrors {
get { return ParseErrors != null && ParseErrors.Count > 0; }
}
public List<string> ParseErrors { get; set; }
public object Parse(string fileName) {}
}
Or whatever error type you wanted of course, something with more detail maybe.
Code calling your library would look something like this:
var p = new Parser();
var o = p.Parse("file.txt"); //Get object
if(p.HasErrors) //Uh oh, abort, do something with p.ParseErrors