Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return correct results and list of errors [closed]

I am puzzled by the following design of the method:

Map<String, BigDecimal> foo(Parameter p){ ... }

This method takes a complex Parameter and returns a map name -> value. In many cases, based on certain underlying calues of the parameter, the resulting map will be the same, furthermore, there are only a few different maps that can ever be returned, so these will be cached. However, when the map is initially created, there can potentially be different types of errors - certain String value might be incorrect, certain value might be < 0 and therefore should be skipped etc. These errors might be of different nature then. I would like to return this map, but also be able to flag these errros, ideally only once, when the initialization of each map is performed. What would be the cleanest way to do this?

like image 541
Bober02 Avatar asked Nov 22 '25 01:11

Bober02


2 Answers

This is a fairly unusual requirement - if you can generate a valid result in spite of the internal errors, you should probably return that result; and if not, throw the exception.

But if you do want to return this additional information, then I see you have broadly two options available:

  1. Object-oriented, mutable state. When you're running foo(), accumulate any internal errors in some field. Expose an additional getFooErrors() method to allow callers to inspect what happened. And possibly a getFooErrorSeverity() method if you need to tell callers the degree to which these errors impacted on the quality of your result map.
  2. Immutable/functional. Return the information from above (exceptions and maybe a severity score) as part of your method. Instead of returning a Map<String, BigDecimal>, return an object which contains the map, as well as the exception details. E.g:

    public class FooResult {
        public final Map<String, BigDecimal> result;
        public final List<Throwable> errors;
        public final int errorSeverity;
    
        // Constructor elided
    }
    

The first approach is similar to how java.io.PrintWriter works in the standard library. It swallows any IOExceptions encountered by its I/O methods, and exposes a checkError() method to allow callers to see if the writer encountered any exceptions.

I prefer the second because it doesn't impact thread-safety, it gives the client all the information up-front, and it's neatly coupled with the scope where the error was encountered.

like image 89
Andrzej Doyle Avatar answered Nov 23 '25 15:11

Andrzej Doyle


There is no one right way to do this, but what about creating special class FooResult that would contain your map and list of errors (although I would rather call it a Warning, since unrecoverable errors are usually reported with exceptions), eg:

FooResult foo(Parameter p){ ... }

class FooResult {
  Map<String, BigDecimal> result;
  List<Error> errors;
}

where Error could be a class containing all error information you need (eg. code, message, exception, etc), for instance:

class Error {
  int code;
  String message;
  Throwable cause; // optional, depending on error
  // ...
}

Alternatively the list of Errors could be passed as a parameter and filled by the method if necessary, eg:

Map<String, BigDecimal> foo(Parameter p, List<Error> errors) { 
  ... 
  if (error) {
    errors.add(new Error(10, "Bad error"));
  }
}
like image 43
Adam Dyga Avatar answered Nov 23 '25 15:11

Adam Dyga



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!