Denis Kulagin
Denis Kulagin

Reputation: 8937

Java: proper design for multierror functionality

I am writing piece of code in Java, which job is to parse configuration file. It's convenient for the end-users, because they can see and fix all parsing errors at once. But it's not very good for testing - instead of specific exceptions test function just expects very general ParsingError exception.

It's always a room for dark magic here, like testing private methods, but I don't want to go for it. Could you suggest better design solution for the case?

Upvotes: 0

Views: 88

Answers (4)

jmkgreen
jmkgreen

Reputation: 1643

I have been here before. Exceptions are unsuitable. Instead you should provide a report inside your parser.

parser.parse();
if (parser.hasErrors()) {
    for (ParserError error : parser.getErrors()) {
        // Provide a report to the user somehow
    }
}

Simple and easy to read. An exception should be thrown if there is an exception condition - e.g. there is no source data to parse, not because the parser found problems.

Upvotes: 1

Arnaud Potier
Arnaud Potier

Reputation: 1780

First things first: ParsingError seems a strange name, ParsingException looks better (Error is a java.lang class that should not be caught)

You could add a list in your ParsingException and add a try-catch block in your test in which you test that your list contains what you expect.

For example you had:

@Test(expected=ParsingException.class)
public void test_myMethod_myTestCase(){
        myMethod()
}

but then you would have:

public void test_myMethod_myTestCase(){
    try {
        myMethod()
    }
    catch(ParsingException pe) {
        if (! pe.list.contains(anError)
            || ! pe.list.contains(anOtherError) ) {
            fail();
        }
    }
}

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234785

Why not use chained exceptions? You could build specific exceptions (say ParticularParsingError), then chain this with ParsingError and throw that back.

In your unit tests, use e.getCause() where e is a ParsingError.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1502256

Why not throw just a single InvalidConfigurationException (I wouldn't use ParsingError - aside from anything else, I wouldn't expect this to be an Error subclass) which contains information about the specific problems? That information wouldn't be in terms of exceptions, but just "normal" data classes indicating (say) the line number and type of error.

Your tests would then catch the exception, and validate the contents was as expected.

The implementation would probably start off with an empty list of errors, and accumulate them - then if the list is non-empty at the end of the parsing code, throw an exception which is provided with that list of errors.

Upvotes: 1

Related Questions