Returning status messages - java

There are methods in classes like "addSomething()". This can be successful or not successful. The status of the success can therefore be displayed with a boolean return value. But sometimes a method invocation can fail because of several reasons. "false" displays that, but only in a general manner. Sometimes the programmer wants to know the reason, why something failed. Is it, for this purpose, useful to provide an own report class that offers functionality like that?
public class Report {
private final boolean success;
private final String message;
public Report(boolean success) {
this.success = success;
this.message = "empty message";
}
public Report(boolean success, String message) {
this(success);
this.message = message;
}
public boolean wasSuccessful() {
return success;
}
public String getMessage() {
return message;
}
}
Then you can decide if you want to get a general success report with "wasSuccessful()" or if you also want to log the exact reason with "getMessage()".

Is it, for this purpose, useful to provide an own report class that offers functionality like that?
"Usefulness" is subjective. If the above is what nicely solves your specific problem, then of course it is useful, and might be a good approach.
But in general, failure in Java is typically modelled by using exceptions of some wort.
Therefore, in many situations you simply go with void methods. As: the method just returning means: "all fine". Otherwise, if there was some problem, the method throws an exception at you.
Now, if on the other hand, you have situations where a method might pass or fail, and both outcomes are fully okay (for example if some method checks whether an optional parameter is present), then sure: your approach can be useful. You simply allow to add new Report objects for each method invocation that matters to you. And then whoever calls the method can create Report objects and add them to some context-specific ReportCollector.
But note: the real issue in my eyes: when you think about programmatically collecting (and using) such "progress" information, then message strings quickly turn into a problem. There is a good reason why people sometimes use numerical error ids: to enable programmatic handling of such situations. Strings only carry meaning for humans who read them.
Your code can't do much with strings. Remember: doing a contains("this") or contains("that") to determine how to react to error (messages) later on, that is a real anti pattern!

You can try to use smth like Either pattern.
It's used like Either<Report,Error> in each moment you will have either a valid report or an object with errors.

Related

use case/business logic returning multiple values best practice?

I am implementing a clean architecture in an application. I have a layer where the application/usecase classes which does the business logic and interacts with mutliple outgoing ports (interfaces to adapters for database calls, http api calls etc). The usecase returns a value/model to a web controller (Which renders the output to the user of the app).
Due to the complexity of the business logic there are many sad paths and a happy path (which are different types of objects with different state), as well as exceptions which can bubble up to the web controller. Exceptions are handled by an error handler with a generic http response and logged.
To return the happy and sad paths, I have wrapped it in an object of two fields. But I feel this is a code smell, as I will always have one field returning null. So in the web controller/servlet there are checks on the populated field to determine the correct http response. Is this a good way of doing this?
I have seen usecases, return the happy path, and all sad paths are given a specific business exception. This exception is caught at the web controller/servlet, and creates the http response using the exception message. I feel this is a code smell too, as we are using exceptions as control flow in the web controller/servlet.
I have seen other ways of returning multiple values such as
using a tuple
Having one object returned, but each field is a list, thus removing the need for a null as an empty field, and using an empty list
Using a map
Are there any other ways of returning multiple values, without having null fields or using exceptions (as explained above)?
Are there any other ways of returning multiple values, without having
null fields or using exceptions (as explained above)?
In Java (and POO languages) the usual way to do it is inheritance.
Probably sooner rather than later you'll fall into the Expression problem, that is, you must be careful when to include a process in your class hierarchy, and when to define that process in isolation.
If your process makes sense in the hierarchy, define it in it:
abstract class Response {
abstract boolean isSuccess();
abstract String getMessage();
}
class ErrorResponse extends Response {
boolean isSucess() { return false; }
String getMessage() { return "Something went wrong."; }
}
class SuccessResponse extends Response {
boolean isSucess() { return true; }
String getMessage() { return "Everything went well."; }
}
But you can't expect your hierarchy to contain the logic for any situation, so you can use introspection. Eg. in some view controller:
Color getResponseColor(Response rs) {
if(rs instanceof NetworkErrorResponse || rs instanceof ServerErrorResponse) {
return Colors.WITHOUT_SERVICE_COLOR;
}
return rs.isSuccess() ? Colors.SUCCESS_COLOR: Colors.ERROR_COLOR;
}
As you can see, including color decision making in the class hierarchy wouldn't make much sense.
Finally, since you are going to serialize your messages, you must make sure that the transport protocol supports inheritance.

Vert.x log statement parameterized with a Lambda Expression

I want to add some extra debug information in a project based on Vert.x that happens to use io.vertx.core.logging.Logger for logging.
As far as I can see by looking at the Javadoc, the class doesn't provide a method with a signature matching a functional interface.
The log message I want to output can be based on a sizeable collection of values. I'd like to avoid transforming it unnecessarily.
That seems to leave me with the following pattern:
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(buildMyLargeCollectionsStringRepresentation());
}
This, on the other hand, makes my code check for isDebugEnabled() time and time again.
I'd rather leave it up to the framework for both brevity and potential optimization.
Is there a way to use a supplier in a way similar to the java.util.Logger class?
It doesn't look like it. But with a little care, you can probably do without the guard functions like isDebugEnabled(). Loggers typically check the log level inside of logging functions before formatting the string. If it does decide that the logging level matches, it will do the string formatting, which includes calling toString() on any parameters that are passed in to be included in the formatted string. If you avoid complex expressions passed directly into logger methods and instead encapsulate your expressions in an object whose toString() function evaluates the expression you wish to log, then you might achieve the benefit of the guard expressions without having to use them.
I'm not sure how vertx binds its apis to JUL logging. It may be that the first Object parameter will be passed as the Supplier parameter in JUL. If not, you might try the technique below which can be adapted for any general string logging mechanism that calls toString() on its parameters.
Consider the following, which uses slf4j's parameter notation:
debug("Doing something with {}", some_expression_that_is_expensive);
In this example, some_expression_that_is_expensive would be called every time the debug function is called, whether or not debug logging is enabled. If you instead had a class such as
class EncapsulatedExpression {
#Override
public String toString() {
return some_expression_that_is_expensive;
}
}
Then you could call
debug("Doing something with {}", new EncapsulatedExpression());
And then some_expression_that_is_expensive would only be called if the log level were debug.
You are on the right track by saying that a Supplier would offer similar lazy evaluation in a more general way, so to get what you want you will need a tool to create something that can encapsulate a Supplier, whose toString() will cause the supplier to be evaluated. Perhaps something like this would work:
class ToStringSupplier<T> {
private Supplier<T> supplier;
public ToStringSupplier(Supplier<T> supplier){
this.supplier = supplier;
}
public static <T> ToStringSupplier<T> lazily(Supplier<T> supplier){
return new ToStringSupplier<>(supplier);
}
#Override
public String toString(){
return Objects.toString(supplier.get()); // supplier could safely return null
}
}
You could use it like this:
debug("Doing something with {}", lazily(() -> some_expression_that_is_expensive));

How deep should logging go?

To paint a scenario, consider the following logic-omitted-Service
public class Service {
private Validator validator;
public void submit(Foo foo) {
if (!validator.isValid(foo)) {
log.warn("invalid foo");
} ...
}
}
public interface Validator {
boolean isValid(Foo foo);
}
The problem is that only the Validor itself knows the reason to why the validation would fail. I see only two viable approaches to tuning in on that reason. Either the Validator
logs the failing condition itself
returns a complex object containing a String reason and boolean isValid.
The former is nice but would leave the Service clueless to whether logging is actually performed, and the latter introduces an annoying redudancy and a more complex usage.
Which is to prefer, or, is there a better approach?
You have to ask yourself a question: do your client care about the validation failure reason? And the answer is: it depends. In many cases you would like to inform the end user precisely what was the cause of validation failure. In that case return "complex" validation result object (don't use exceptions here!), essentially wrapping a collection of strings or codes (to allow i18n). The ValidationResult object would be a business object, not some second-class helper.
In other situations you just want to make a decision based on whether the object was valid or not. The calling code (client) couldn't care less about the internal logic of validation. It's either valid or not. Then go for straight boolean method. For debug purposes add logging inside validation method. Turn them on/off depending on your desire.
And you know what's the best part? You can have two methods and use whichever suits better for the client code. Obviously the less complicated boolean method only delegates to more compilcated one and provides simpler view:
boolean isValid(Foo foo) {
validate(foo).isValid();
}
ValidationResult validate(Foo foo) {
//logging and "real" validation
}

Is this an Exception Handling abuse?

I have this method, that can return three different response.
At first, it was supposed just only return two, so I make its return type to Boolean
like:
public static boolean isLoteWaitingForImage()
And some business logic came out with that it can has another result, so the method was modified to
public static boolean isLoteWaitingForImage() throws ImageNotPendingException
If a certain select return a null value, but one row its return true, if its not null i will return false. If no row was acquired from the select I will throw an ImageNotPendingException cause it doesn't apply for the given filters in the where clause.
Also thought about doing it in this Way, I have this new Class with the types that are valid to return from the method isLoteWaitingForImage(), with 3 constants properties called:
public class LoteResponse {
public static int VALID = 1;
public static int INVALID = 2;
public static int NO_IMAGE_PENDING = 3;
}
So I will have this new method:
public static int isLoteWaitingForImage() {
return LoteResponse.VALID;
}
Having this on table, I have these two questions:
Any "other" idea about how to accomplish this needing?
Which method is a better practice?
Yes, that looks like an abuse to me.
It would be reasonable to throw the exception if the method simply shouldn't be called when no image is pending. Can the client always know that? Does it represent a bug, or something else going badly wrong for them to be calling it in that state? If not, don't use an exception.
It looks to me like you need an enum.
public enum LoteResponseState
{
Valid,
Invalid,
NoImagePending;
}
public static LoteResponseState getLoteState()
{
...
}
If you expect the code that calls isLoteWaitingForImage() to be directly responsible for handling the "no image pending" condition as well as the others, then use the multiple return values, but use an enum, not ints!
If the "no image pending" condition cannot be usefully handled by the immediate calling code and instead would usually be handled higher up the call stack, then the exception is the better option.
I definitely agree that an enum is the best choice.
As a general rule, if a certain operation is not considered a serious error that will rarely occur, you should not throw an exception. Throw exceptions only for errors that the current method cannot have any way of handling in a useful way, but not as a typical return value.
I am no expert so don't take this as a best-practice advice, but I think using exceptions in this particular case seems like an overkill. I would go for some simple return values as mentioned above.
If you really want to keep track of the situation, for whatever debugging or developing reason, you could perhaps throw RuntimeException("why a runtime exception is thrown") instead. Writing an own Exception seems too excessive if you are not doing something particular with the exception.
I hope that makes some sense. :)
Go for the exception way. It does have a more explicit interface to the caller. If the caller needs to process this ImageNotPendingException make it an Checked Exception.
Returning enum is a bizarre thing as it diminishes encapsulation by delegating business detail and processing to the caller. This way the caller needs to know way too much of the calee.
Sorry about my bad english.

Best way to return status flag and message from a method in Java

I have a deceptively simple scenario, and I want a simple solution, but it's not obvious which is "most correct" or "most Java".
Let's say I have a small authenticate(Client client) method in some class. The authentication could fail for a number of reasons, and I want to return a simple boolean for control flow, but also return a String message for the user. These are the possibilities I can think of:
Return a boolean, and pass in a StringBuilder to collect the message. This is the closest to a C-style way of doing it.
Throw an exception instead of returning false, and include the message. I don't like this since failure is not exceptional.
Create a new class called AuthenticationStatus with the boolean and the String. This seems like overkill for one small method.
Store the message in a member variable. This would introduce a potential race condition, and I don't like that it implies some state that isn't really there.
Any other suggestions?
Edit Missed this option off
Return null for success - Is this unsafe?
Edit Solution:
I went for the most OO solution and created a small AuthenticationResult class. I wouldn't do this in any other language, but I like it in Java. I also liked the suggestion
of returning an String[] since it's like the null return but safer. One advantage of the Result class is that you can have a success message with further details if required.
Returning a small object with both the boolean flag and the String inside is probably the most OO-like way of doing it, although I agree that it seems overkill for a simple case like this.
Another alternative is to always return a String, and have null (or an empty String - you choose which) indicate success. As long as the return values are clearly explained in the javadocs there shouldn't be any confusion.
You could use exceptions....
try {
AuthenticateMethod();
} catch (AuthenticateError ae) {
// Display ae.getMessage() to user..
System.out.println(ae.getMessage());
//ae.printStackTrace();
}
and then if an error occurs in your AuthenticateMethod you send a new AuthenticateError (extends Exception)
Avoid returning a "sentinel value", especially null. You will end up with a codebase where methods cannot be understood by the caller without reading the implementation. In the case of null, callers may end up with NullPointerExceptions if they forget (or don't know) that your method may return null.
The tuple suggestion from Bas Leijdekkers is a good one that I use all the time if I want to return more than one value from a method. The one we use is P2<A, B> from the Functional Java library. This kind of type is a joint union of two other types (it contains one value of each type).
Throwing Exceptions for control flow is a bit of a code smell, but checked exceptions are one way of getting more than one type of value from a method. Other, cleaner possibilities exist though.
You can have an Option<T> abstract class with two subclasses Some<T> and None<T>. This is a bit like a type-safe alternative to null, and a good way to implement partial functions (functions whose return value isn't defined for some arguments). The Functional Java library has a full-featured Option class that implements Iterable<T>, so you can do something like this:
public Option<String> authenticate(String arg) {
if (success(arg))
return Option.some("Just an example");
else
return Option.none();
}
...
for(String s : authenticate(secret)) {
privilegedMethod();
}
Alternatively, you can use a disjoint union of two types, as an Either<L, R> class. It contains one value which is either of type L or R. This class implements Iterable<T> for both L and R, so you can do something like this:
public Either<Fail, String> authenticate(String arg) {
if (success(arg))
return Either.right("Just an example");
else
return Either.left(Fail.authenticationFailure());
}
...
Either<Fail, String> auth = authenticate(secret);
for(String s : auth.rightProjection()) {
privilegedMethod();
}
for(Fail f : auth.leftProjection()) {
System.out.println("FAIL");
}
All of these classes, P2, Option, and Either are useful in a wide variety of situations.
Some more options:
Return an separate enum value for each type of failure. The enum object could contain the message
Return an int and have a separate method that looks up the appropriate message from an array
create a generic utility tuple class that can contains two values. Such a class can be useful in many more places.
simple tuple example, actual implementation may need more:
class Tuple<L, R> {
public final L left;
public final R right;
public Tuple( L left, R right) {
this.left = left;
this.right = right;
}
}
You could return a Collection of error messages, empty indicating that there were no problems. This is a refinement of your third suggestion.
I personally think creating a new class called AuthenticationStatus with the boolean and the String is the most Java like way. And while it seems like overkill (which it may well be) it seems cleaner to me and easier to understand.
Just because failed authentication is commonplace doesn't mean it isn't exceptional.
In my opinion, authentication failures are the poster-child use case for checked exceptions. (Well... maybe file non-existence is the canonical use case, but authentication failure is a close #2.)
I use the "tiny class" myself, usually with an inner class. I don't like using arguments to collect messages.
Also, if the method that might fail is "low level" - like coming from an app server or the database layer, I'd prefer to return an Enum with the return status, and then translate that into a string at the GUI level. Don't pass around user strings at the low level if you're ever going to internationalize your code, because then your app server can only respond in one language at a time, rather than having different clients working in different languages.
Is this the only method where you have such a requirement? If not, just generate a general Response class with an isSuccessful flag and a message string, and use that everywhere.
Or you could just have the method return null to show success (not pretty, and does not allow returning a success AND a message).
I would most probably go for something like :
class SomeClass {
public int authenticate (Client client) {
//returns 0 if success otherwise one value per possible failure
}
public String getAuthenticationResultMessage (int authenticateResult) {}
//returns message associated to authenticateResult
}
With this "design", you can ask for a message only when authentication fails (which I hope is the scenario that occurs 99,99% of time ;))
It may also be of good practice to delegate message resolution to another Class. But it depends of your application needs (mostly, does it need i18n ?)
This seems like a common idiom in other programming languages, but I cannot figure out which one ( C I guess as I read in the question ) .
Almost the same question is posted here and here
Attempting to return two values from a single function, may be misleading. But as it has been proved by the attempts of doing so, it may be very useful too.
Definitely creating and small class with the results should be the correct way to proceed if that is a common flow in the app as posted before.
Here's a quote about returning two values from a function:
As a matter of programming style, this idea is not
appealing in a object oriented programming language.
Returning objects to represent computation results
is the idiom for returning multiple values. Some
suggest that you should not have to declare classes
for unrelated values, but neither should unrelated
values be returned from a single method.
I've found it in a feature request for java to allow multiple return values
look at the "evaluation" section dated: 2005-05-06 09:40:08
Successful authentication should be the "normal" case, so an authentication failure is the exceptional case.
What are the different status strings for the user anyway. I can see only two, success or failure. Any further information is a potential security issue.
Another advantage of the solution with exceptions is that it cannot be called in the wrong way and the failure case is more obvious. Without exceptions, you write:
if (authenticate()) {
// normal behaviour...
}
else {
// error case...
}
You can accidently call the method ignoring the return value. The "normal behaviour" code is then executed without successful authentication:
authenticate();
// normal behaviour...
If you use exceptions, that cannot happen. If you decide to not use exceptions, at least name the method so that it is clear that it returns a state, e. g.:
if (isAuthenticated()) {
//...
}
There are a lot of good answers here so I will keep it short.
I think failure of a user to authenticate can be considered a valid case for a checked exception. If your style of programming favoured handling exceptions then there would be no reason not to do this. It also removes the "How to return multiple values from a method, my method does one thing It authenticates a user"
If you are going to return multiple values then spend 10 minutes creating a generic PairTuple (can also be more than a pair TripleTuple, I won't repeat the example listed above) and return your values that way.
I hate having small dto style objects to return various multiple values they just clutter the place.
How about returning a string. Empty or Null for success. Error Message in case of failure.
Simplest that would work. However not sure if it reads well.
Return the Object. It allows you to put additional functionality into the Class if you need it. Short lived objects in Java are quick to create and collect.
I would choose the Exception option in first place.
But, in second place, I would prefer the C-style technique:
public boolean authenticate(Client client, final StringBuilder sb) {
if (sb == null)
throw new IllegalArgumentException();
if (isOK()) {
sb.append("info message");
return true;
} else {
sb.append("error message");
return false;
}
}
This is not so strange and it's done in many places in the framework.
Instead of creating a special object for return type, I usually just return an array where all the returned information is stored. The benefit is that you can extend this array with new elements without creating new types and mess. The downside you have to know exactly what elements should present when array is returned from particular method to parse it correctly. Usually I agree on certain structure, like first element is always Boolean indication success, second is String with description, the rest is optional.
Example:
public static void main(String[] args)
{
Object[] result = methodReturningStatus();
if(!(Boolean)result[0])
System.out.println("Method return: "+ result[1]);
}
static Object[] methodReturningStatus()
{
Object[] result = new Object[2];
result[0] = false;
result[1] = "Error happened";
return result;
}

Categories

Resources