Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Typically Geode handles failure by exception; If an issue is encountered while executing code, an exception is thrown and propagated up until either it is caught or it crashes the system. It's too easy to miss an exception and allow it to crash Geode or swallow it without reporting an the error at all. Exceptions may also be caught, wrapped, and rethrown multiple times on their way up the stack so, by the time they reach the surface, all context on the root cause of failure is lost. This isn't ideal because we obviously don't want the system to go down, but we definitely want to know when a failure occurs and what caused it. Since exception handling is dangerous and messy as well as expensive, it is best to avoid it when possible.

...

Fortunately, there are other ways to handle failure besides exceptions–just return a normal type that may contain either a result or an error. This isn't a new concept, errors are handled this way as normal return types in Go and even in parts of Geode. That's right, this idea is already being used by geode-protobuf and in the work related to the ClassLoader Isolation RFC. The proposed solution is to use this more functional approach to error handling in more places throughout Geode by introducing a new generic Result interface. A Result will represent the result of an operation and take two type parameters, a SuccessType and a FailureType. The SuccessType will be the expected result of the operation and the FailureType will be the type to return if the operation fails. The Result interface will have methods to...

...

To make the Result simpler to use, there will be another interface called ServiceResult that will extend Result. ServiceResult will only take one type-parameter, SuccessType, and will use String as the FailureType to be able to return an error message. ServiceResult also adds some useful methods to allow interaction with the Result using lambdas. can also add convenience features such as lambda support.


There will be two concrete implementations of ServiceResult: Success and Failure. Success will carry contain a result of SuccessType and identity itself as successful when asked. Failure will carry a String contain an error message and identify itself as a failure. A method that uses this new way of handling results should return a Success with the result when the operation succeeds and a Failure with a meaningful error message when something goes wrong. The caller can then check whether the operation succeeded or failed and act accordingly by retrieving the result, or handling the error as they see fit (ignore it, print the error message, exit, recover, etc.). Note that trying to get a result from Failure or trying to get an error message from Success is to not allowed and will result in an exception being thrown–you should check for success or failure before attempting to access the result or error message. While throwing an exception here isn't ideal, it's necessary for some circumstances.

...

Scenario 1: An operation completes successfully.

Expected behavior: A Success object is returned. Calling isSuccess() on the Success returns true and calling isFailure() returns false. The Success contains the result of the operation (SuccessType).


Scenario 2: An operation encountered an error.

Expected behavior: A Failure object is returned. Calling isFailure() on the Failure returns true and calling isSuccess() returns false. The Failure contains an error message describing the error.


Scenario 3: isSuccess() is called on a Success.

Expected behavior: true is returned.


Scenario 4: isSuccess() is called on a Failure.

Expected behavior: false is returned.


Scenario 5: isFailure() is called on a Success.

Expected behavior: false is returned.


Scenario 6: isFailure() is called on a Failure.

Expected behavior: true is returned.


Scenario 7: You attempt to retrieve the result from a Success.

Expected behavior: the result is returned.


Scenario 8: You attempt to retrieve the result from a Failure.

Expected behavior: a RuntimeException is thrown.


Scenario 9: You attempt to retrieve the error message from a Success.

Expected behavior: a RuntimeException is thrown.


Scenario 10: You attempt to retrieve the error message from a Failure.

Expected behavior: the error message is returned.

Changes and Additions to Public Interfaces

...