Permalink
Browse files

Add OptionalResult

This helps reducing the places where problems are communicated via RuntimeException
and also reduces cases where nullable objects are returned and not properly handled.

The old pattern in Little Goblin is:
1. if(problem){throw new RuntimeException(errorMessage))
2. catch RuntimeException e, render error message from e.getMessage (this breaks with unexpected exceptions lacking a proper messageId...)

The new pattern should be:
1. for each problem: add error to OptionalResult
2. return OptionalResult and handle valid/invalid case from there

The old pattern mixes serious exceptions with common user errors (for example, using a too-short password),
it often uses expensive Exception objects (with complete StackTraces) and can only ever communicate one problem.
You can work around the expensive objects problem by using static exceptions, but it's still ugly.
  • Loading branch information...
dewarim committed Nov 2, 2014
1 parent 1e70585 commit 92354e0dd102bf5cfa77168a1f22eb9a04d7c227
Showing with 46 additions and 0 deletions.
  1. +46 −0 src/groovy/de/dewarim/OptionalResult.groovy
@@ -0,0 +1,46 @@
+package de.dewarim
+
+/**
+ * Result class object using an Optional<T>.
+ * This helps reducing the places where problems are communicated via RuntimeException
+ * and also reduces cases where nullable objects are returned and not properly handled.
+ */
+class OptionalResult<T> {
+
+ List<String> errors
+
+ private T resultObject
+
+ OptionalResult() {
+
+ }
+
+ OptionalResult(T resultObject) {
+ this.resultObject = result
+ }
+
+ OptionalResult(List<String> errors){
+ this.errors =errors
+ }
+
+ OptionalResult(String error){
+ addError(error)
+ }
+
+ Optional<T> getResult(){
+ return Optional.ofNullable(resultObject)
+ }
+
+ Boolean hasErrors(){
+ return errors?.isEmpty()
+ }
+
+ void addError(String error){
+ if(errors == null){
+ errors = [error]
+ }
+ else{
+ errors.add(error)
+ }
+ }
+}

0 comments on commit 92354e0

Please sign in to comment.