What is the standard template for a method that may fail for various reasons?

Let's say I have a method that will post content on the Internet and return true / false representing success / failure.

However, my method may work with an error at different stages, for example:

  • Blocked by spam blocker
  • Network error
  • Unexpected exception

I still want the method to simply return a boolean, I also don't like the idea of ​​letting the method just throw its exception, and every caller should wrap it in try / catch (I hate try / catch, it is always ugly).

Is there a standard solution to this problem?

The best solution I've come across is to make it return an enumeration with various possible results, then the caller has a switch statement. Is there a better solution than this?

EDIT: I should have been more clear; this is an Android application, the user will post comments on the Internet, various errors will be translated into messages for the user, for example. "Spam, wait before retrying"

+5
source share
4 answers

Return enum is ok. But if you are going to call it from many places, you will have the same error handling code in several areas (i.e. the same switch ).

Perhaps one approach is to return a logical, but encapsulate specific error handling logic inside the error handler. Thus, you define an interface like this:

 interface PostErrorHandler { void handle(...); } 

Then you can have specific implementations:

 public class SpamErrorHandler implements PostErrorHandler { @Override public void handle(...) { ... //code to deal with spam } } 

Your method signature for publishing will be as follows:

 public boolean post(String content, PostErrorHandler handler) { ... } 

Then you call handler.handle(...) based on the error starting with post .

If you still want to report an error, you can use the approach you mentioned: return enum instead of a boolean.

Regarding exceptions, more than ugliness, the main reason why using exceptions here is a bad idea is because it seems like errors like this are expected. If so, you expect the caller to deal with them in some way, and they seem to be part of your business logic. But using exceptions is not the correct way to make these errors. Usually you want to use exceptions only if something unexpected happens. If you should throw an exception, then it is better to have some kind of status check / check method that checks the input to warn you if the input is bad. In this case, you can throw an exception (make it unchecked) because the situation is unexpected, since you expect the caller to use the state check method before calling the method.

+3
source

Enum may work, but since your method will β€œpost content on the Internet,” perhaps consider using HTTP response codes as a guide.

Without going into details about the many HTTP response codes , be aware that for your examples:

  • Blocked by a spam blocker may be 403 (Forbidden) or something like this
  • Network error maybe 503 (Service Unavailable) maybe
  • An unusual exception is pretty much the exact meaning of the 500 error.

You can return an integer from your method. Then success will be defined as a return code of 100, which is less than 4.

Hope this helps.

0
source

You must overcome your irrational hatred of try / catch. It is not true that all callers should wrap the call in try / catch; this can be done reasonably at different levels of code, if necessary; for example, only the very top level of your application should worry about intercepting "out of memory" or "eject disk". Meanwhile, the try / catch construct can be used with other keywords (e.g. finally ), you will have access to nested exceptions and stack traces, and in general there will be a much richer debugging experience.

On the other hand, if you just want a boolean, the CLR uses a naming pattern that is very common. You would provide two functions that perform essentially the same thing.

 try { string output = MakeSomeFunctionCall(input); } catch { } 

... sometimes complemented by an affiliate function that does the same thing, but returns a boolean value, for example

 string output; bool success = TryMakeSomeFunctionCall(input, out output); 

This enables the user to use try / catch (if detailed error information is required) or by using the "Try *" method (if detailed error information is not required).

Use this template, and for others it should be clear what is going on in your code.

0
source

To be honest, I am of the opinion that "there is a [very good] reason why we started throwing exceptions instead of using return codes.

An essential problem of the return-code approach is that each client must take into account and correctly process each return code with each call.

... And besides, he is obliged to do all this, even when ("as it almost always happens ...") nothing happened.

When the library instead throws an exception, the client does not need to check if the request succeeded. (β€œIf we are still alive, then it succeeded.”) Now the client can catch certain exceptions that it can foresee, and also allow any unsolved exceptions to β€œbubble” with the external level handler.

I sincerely believe that there was wisdom in this strategy.,

0
source

All Articles