简体   繁体   中英

java - is there a standard way of collecting exceptions?

I have a Java program that parses several different input files. Even when an error is found in this input files, parsing could still continue and collect several other errors too. So what I want to do is instead of throwing and exception and stopping parsing process, I'd like to register the exception to somewhere, and then continue parsing and collect several other errors in similar way, then in the end I want to check if any errors are reported, and fail or continue depending on this.

Of course I can always do this manually by writing ExceptionRegister or whatever classes but I want to know two things:

1) Is there a problem with this approach? Do you know any alternative designs for what I want to do?

2) Is there a standard way of doing this? (eg instead of rolling my own classes I'd like to use built-in functionality if possible)

Thanks

EDIT: I don't know why but someone just removed his answer just before I accepted his answer. Anyway, I think simple data structures should work. Basically, I'll write an exception class that collects several error messages. Then I'll call it's throw method which throws itself if it has at least one error message registered.

EDIT2: Here are more clarifications. My problem has nothing to do with parsing. Parsing was just an example because my program does some parsing. Think this: I'm running an algorithm and in case of an error, I can continue the algorithm to collect more errors so that instead of printing one error and when it's fixed, printing second error, I can print this two errors together.

Exceptions should really be used when you can't handle the input anymore. They are the special case where your code says "I give up, I'm missing some information or I wasn't meant for this". This is a grey area on how to define such cases, but the usual philosophy, as put by Bill Venners in this (old!) article is:

Avoid using exceptions to indicate conditions that can reasonably be expected as part of the typical functioning of the method.

In your case, it sounds like the content you have to parse might be incorrect, but this is expected by your program and doesn't break enough the contract to stop the parsing. On the other hand, an acceptable exception would be valid to use if an error in the syntax of the input causes the rest of the interpretation to fail, for example.

But people still uses exception because they are quite convenient for stopping execution and going up the stack without going in the tedious details of flowing through returns of results. But on its counterpart, they can have tricky results as you leave some unattended state in some objects.

Your requirements sounds more like a validation pattern is required than one single exception that could cause the processing to stop. One exception to stop all processing: if you throw one, the rest will be ignored. But you suggested that you would collect them instead of throwing those. So I'd say, in that case, why use exceptions at all? It seems you do want to return proper results and not stop the program's execution.

Because if you still go down this path, you could have a collection of exceptions to throw at the end. Which one do you throw? Which one takes precedence, in the Exception collector you created?

Take the example of Eclipse, which has this gigantic platform to handle with a massive collection plug-ins contribution. They use a proper communication channel to log any warning and errors, either in problems pane or through the execution of background task . The latter's execution will usually return an IStatus object or a variant. Based on this IStatus object, the code that receives the status decides to act upon it.

Hence personally, I'd develop a similar object that would collect all necessary user's errors (and not program's errors), that does not break the program's execution and an acceptable part of the contract. This object can contain the severity of the error, its source, a hint on how to fix it (this can be a string, or even a method that contains a pinpointing logic for showing the error or possibly a partial automated fix), etc... Once the execution is done, the parsing's result will get these status objects and act on it. If there are errors, inform the user through the UI and log it as well.

So it's basically the same approach as you initially suggested, minus the exceptions and minus the commodity of jumping through the stack that could lead to nasty side-effects and very difficult to debug errors.

I think I understand now. What you are actually trying to do is to collect the parse errors (which you are representing as exceptions) and continue parsing the current input file.

There is no standard way to do this:

The "exception register" is really nothing more than a list of parse error descriptors ... presumably some parser exception. If you can catch the exception at the appropriate point, it is trivial to add it to the "register".

The difficult part is the functionality you are not talking about:

  • How to capture the location of the error

  • How to get the parser to continue parsing when it gets a parser error.

The solutions to these depend on how you have implemented your parser.

  • If you are using a parser generator, there is a good chance that the PGS documentation explains how to implement this.

  • If you are implementing the parser by hand, you will need to roll your own code to track error locations and do syntax error recovery.


Basically, I'll write an exception class that collects several error messages. Then I'll call it's throw method which throws itself if it has at least one error message registered.

That sounds like an abuse of exceptions. A better idea is to accumulate the errors in a list, and then create / throw the exception if the list is non-empty. Use a static method in a helper class if you want to avoid duplicating code.

An exception that conditionally throws itself is (IMO) bizarre! And creating lots of exceptions that you are unlikely to throw is likely to be inefficient. (Depending on the JVM, the expensive part of exceptions is often creating the exception and capturing the stack frames. The expense can be significant.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM