returning java.util.Optional or throw (Checked/Unchecked)exception - option-type

I need to create a method to find an employee by employee's name. There are three possible solution to implement this as below :
Employee findEmployeeById(long empId) throws NoSuchEmployeeCheckedException;
Optional findEmployeeById(long empId);
Employee findEmployeeById(long empId) throws NoSuchEmployeeUnCheckedException;
The first method will returning an instance of employee if the id matched in my repository, otherwise throw an instance of check exception NoSuchEmployeeCheckedException
The second method will returning an instance of java8's Optional, while no exception throw.
The last method is similar with the first one , but throw an instance of UnCheck exception NoSuchEmployeeUnCheckedException instead of checked exception.
I have read multiple posts on StackOverFlow about checked vs unchecked exceptions. I'm honestly still not quite sure how to use them properly.
Joshua Bloch in "Effective Java" said that
Use checked exceptions for recoverable conditions and runtime exceptions for programming errors (Item 58 in 2nd edition)
Is the findEmployeeById a recoverable conditions?
Do i need to use Optional or throw exception?
which solution is best?

Use exceptions for exceptional circumstances, if it is commonly expected for no employee to be found then you probably shouldnt use an exception.
Exceptions also have some runtime overhead as they need to capture the stack trace.
In this circumstance I would use either an Optional or if multiple employees can have the same name, return some type of Collection, use an empty collection if no employee is found.

Related

Grails: situation where .validate() works but .save() will fail

If a domain class will validate can I be assured it will save (assuming nothing super-drastic like the database is down)? More explicitly, under which scenarios will an object pass validation but throw an error on save.
under which scenarios will an object pass validation but throw an error on save.
Domain class constraints can check anything, so if "the thing they check" changes between the calls to validate() and save(), then it's entirely possible that the former will succeed and the latter fails.
Here's a very simple such example
Book.ISBN has a unique contraint
myBook.validate() is called and passes
another book with the same ISBN as myBook is saved
myBook.save() fails because the unique constraint on ISBN now fails
Save will throw an error if your database has additional constraints that don't allow the insert or update to succeed. If your database doesn't have any additional constraints and barring any sort of infrastructure outages, I can't think of any reason save() would fail if validate() is true.

Confused with Uncle Bob explanation on handling Null objects in book Clean Code

I was reading Uncle Bob book today on Exception handling and what I could recollect from handing null values was that methods should not be handling null values because it clutters the code. I am a little confused with it.
I have always thought that a method should always make sure that it's dependencies are not null (unless they are injected in constructor and constructor assures of nullability).
For example, if I have a method
public void SendMessage(IEmailSender emailSender, contactList list)
{
if(emailSender == null)
{
throw new ArgumentNullException("Failed to send
message.",MethodBase.GetCurrentMethod().GetParameters[0].Name);
}
if(list == null)
{
throw new ArgumentNullException("Failed to send
message.",MethodBase.GetCurrentMethod().GetParameters[1].Name);
}
// rest of code goes here
}
Am I missing something?
There are two perspectives:
On the one hand, with your approach you would always tell the caller what exactly he did wrong by calling your method. Which is great for the caller because he can fix it right away when he gets your exception. This would be true and valid if you where writing API code that is used by a third party.
On the other hand, if you call your method yourself, a reasonable argument to throw an exception is, because you want to be able to handle this situation with a catch block inside your calling code! If you have no reason to handle it somewhere, why throwing an exception at all? The only reason i see is, to have a detailed error logging by catching those exceptions in a GlobalExceptionHandler.
So you see we have two categories of exceptions here: The one for developers, to avoid wrong usage of APIs, and the other one to be used as the method's error-result.
If you are writing API code that will be used by others, your choice would be, not to listen to Bob ;-)
For those who did not read CleanCode, Bob is suggesting two things:
1.You should not write methods that return null (To avoid unnecessary checks afterwards). So Instead of writing this:
var myObject = GetObjectThatDoesSomthing();
if(myObject != null)
{
myObject.DoSomething();
}
... you should be able to write this:
var myObject = GetObjectThatDoesSomething();
myObject.DoSomething();
Cleaner.
2.You should not pass null to your methods to avoid unnecessary checks at the beginning of a method, like here:
public Point Add(Point p1, Point p2)
{
if(p1 == null) throw ArgumentException();
if(p2 == null) throw ArgumentException();
...
}
The point of these rules is: if you stick with it, you know that you dont have to write these null-checks and your code gets cleaner and easier to read. But at the moment you are using third party code, you are not able to tell if they have applied the same rules in their API, so you are starting to pre- or postcheck again. The same thing when you write an API for others: How do the consumers of your API know that you have coded with Bobs rules in mind...
I haven't read the book but I can only imagine that Uncle Bob is advocating the use of the Null Object Pattern in preference to explicit null reference handling.
for example, rather than
if(log != null)
log.Write("My log message");
You could instead create an ILogger interface containing a Write method and create two classes that implement this interface: a NullLogger and a FileLogger. The NullLogger would have an empty body for the Write method's implementation.
In my mind this is different to your explicit pre-condition validation that you have in your example
It depends what type of code are you writing.
If your public method is designed to be used by the wide range of developers non familiar with usage it makes always sense to check parameters and throw a verbose exception.
If you are writing a private method which is only used from the same class or some internal called by another friendly class also written by you or by your collaborator it makes less sense to make paranoia null checks. Your injection design and tests must ensure your internas are not getting null values.
And if private/internal method parameters still get nulls it is anyway too late. Throwing ArgumentNull exception form a private/internal method does not help external user to fix the cause, so it makes no difference for him either to get ArgumentNull or NullReference exception.

"Validation that might throw exception" - Naming convention and semantics

If you validate something in code you can either work with a return value indicating that something is wrong or you can throw an exception. In my controller I have Exceptional validation like this:
void DoSomething()
{
Validate(); // throws exception if something is wrong
.....
}
I wonder if there is a common naming convention that implies that an exception is thrown when something is wrong so that I don't need to add the comment // throws exception if something is wrong and distinguishes from if (!IsValid())
Note: validation-naming-conventions does not answer my question.
Update after accepting the answer: What I have learned from this Question
AssertValid() or VerifyAndThrow() are good names (tnx #hacktick)
Validation must distinguish with a context (warning or error)
Exceptional Validation is good as a kind of Contract or second line of defense that might exist only in Debug mode to ensure that the surrounding if (IsValid(...)) does not miss something (tnx # Cody Gray)
Typically you would use:
// for a validations that returns just plain yes no (true|false). in the case of a property use caching for the last validationresult.
bool IsValid
// for a validation that returns a list of errors of some sort (messagelist, id list, custom objects, whatever you need).
object Validate();
// validates and throws an exception if one or more error occured.
void ValidateAndThrow();
Also make sure to consider if you need warnings of some kind. For example if you validate your registration DTO model and want to warn a user if the password is weak but do not want to prevent the user from saving it if he chooses to.

How and when to apply business rules?

Suppose I have a service StateService which has a method ChangeState.
ChangeState(State toState, DomainObject object)
I have business rules that checks whether the destination state is valid or not in the domain objects current "state", how can I technically check those rules without first setting the toState on the domain object? It feels wrong to first set the new state, run validation and if one or more rule breaks unset the state.
One solution I came up with is to create some context object that drives the validation eg.
ChangeStateContext that contains the DomainObject along with the State that is to be set.
Another related question is how to report back from the ChageState call how it went?
I can collect all validation rules that broke and throw an exception with those rules that the caller can catch and handle accordingly or I can add a return type on the ChangeState-method like ValidationSummary that contains information about broken rules and such. What is best practices in these cases?
Can't you throw an exception from the ChangeState method when the state transformation is invalid? You can throw specific exceptions such as StateTransformationException or ValidationException that you can catch higher on the call stack. You can optionally include extra properties to these exception types so that you can communicate very precisely what went wrong to the user.
When you want to call multiple ChangeStates after a single user action, you will need a way to revert or rollback. What I usually do is using the unit of work pattern (supplied to me by LINQ to SQL and Entity Framework) and change all state within this unit of work. When an exception is thrown I throw away the complete unit of work with all its changes.
The DomainObject class could have a public bool CanChangeState(State toState) instance method, returning True if toState is a valid transition from the current state of the subject DomainObject. Such method can be called prior to the StateService.ChangeState call.
Of course, if the StateService is responsible for the state change validation, then a CanChangeState(State toState, DomainObject obj) method should be added to the StateService.
To report back the validation error messages, change the return Type of the CanChangeState to a custom Type responsible for reporting validation errors.

How can I test for an expected exception with a specific exception message from a resource file in Visual Studio Test?

Visual Studio Test can check for expected exceptions using the ExpectedException attribute. You can pass in an exception like this:
[TestMethod]
[ExpectedException(typeof(CriticalException))]
public void GetOrganisation_MultipleOrganisations_ThrowsException()
You can also check for the message contained within the ExpectedException like this:
[TestMethod]
[ExpectedException(typeof(CriticalException), "An error occured")]
public void GetOrganisation_MultipleOrganisations_ThrowsException()
But when testing I18N applications I would use a resource file to get that error message (any may even decide to test the different localizations of the error message if I want to, but Visual Studio will not let me do this:
[TestMethod]
[ExpectedException(typeof(CriticalException), MyRes.MultipleOrganisationsNotAllowed)]
public void GetOrganisation_MultipleOrganisations_ThrowsException()
The compiler will give the following error:
An attribute argument must be a
constant expression, typeof expression
or array creation expression of an
attribute
Does anybody know how to test for an exception that has a message from a resource file?
One option I have considered is using custom exception classes, but based on often heard advice such as:
"Do create and throw custom exceptions
if you have an error condition that
can be programmatically handled in a
different way than any other existing
exception. Otherwise, throw one of the
existing exceptions." Source
I'm not expecting to handle the exceptions differently in normal flow (it's a critical exception, so I'm going into panic mode anyway) and I don't think creating an exception for each test case is the right thing to do. Any opinions?
I would recommend using a helper method instead of an attribute. Something like this:
public static class ExceptionAssert
{
public static T Throws<T>(Action action) where T : Exception
{
try
{
action();
}
catch (T ex)
{
return ex;
}
Assert.Fail("Exception of type {0} should be thrown.", typeof(T));
// The compiler doesn't know that Assert.Fail
// will always throw an exception
return null;
}
}
Then you can write your test something like this:
[TestMethod]
public void GetOrganisation_MultipleOrganisations_ThrowsException()
{
OrganizationList organizations = new Organizations();
organizations.Add(new Organization());
organizations.Add(new Organization());
var ex = ExceptionAssert.Throws<CriticalException>(
() => organizations.GetOrganization());
Assert.AreEqual(MyRes.MultipleOrganisationsNotAllowed, ex.Message);
}
This also has the benefit that it verifies that the exception is thrown on the line you were expecting it to be thrown instead of anywhere in your test method.
The ExpectedException Message argument does not match against the message of the exception. Rather this is the message that is printed in the test results if the expected exception did not in fact occur.
Just an opinion, but I would say the error text:
is part of the test, in which case getting it from the resource would be 'wrong' (otherwise you could end up with a consistantly mangled resource), so just update the test when you change the resource (or the test fails)
is not part of the test, and you should only care that it throws the exception.
Note that the first option should let you test multiple languages, given the ability to run with a locale.
As for multiple exceptions, I'm from C++ land, where creating loads and loads of exceptions (to the point of one per 'throw' statement!) in big heirachies is acceptable (if not common), but .Net's metadata system probably doesn't like that, hence that advice.
I think you can just do an explicit try-catch in your test code instead of relying on the ExpectedException attribute to do it for you. Then you can come up with some helper method that will read the resource file and compare the error message to the one that comes with the exception that was caught. (of course if there wasn't an exception then the test case should be considered a fail)
If you switch over to using the very nice xUnit.Net testing library, you can replace [ExpectedException] with something like this:
[Fact]
public void TestException()
{
Exception ex = Record.Exception(() => myClass.DoSomethingExceptional());
// Assert whatever you like about the exception here.
}
I wonder if NUnit is moving down the path away from simplicity... but here you go.
New enhancements (2.4.3 and up?) to the ExpectedException attribute allow you more control on the checks to be performed on the expected Exception via a Handler method. More Details on the official NUnit doc page.. towards the end of the page.
[ExpectedException( Handler="HandlerMethod" )]
public void TestMethod()
{
...
}
public void HandlerMethod( System.Exception ex )
{
...
}
Note: Something doesn't feel right here.. Why are your exceptions messages internationalized.. Are you using exceptions for things that need to be handled or notified to the user. Unless you have a bunch of culturally diverse developers fixing bugs.. you shouldn't be needing this. Exceptions in English or a common accepted language would suffice. But in case you have to have this.. its possible :)
I came across this question while trying to resolve a similar issue on my own. (I'll detail the solution that I settled on below.)
I have to agree with Gishu's comments about internationalizing the exception messages being a code smell.
I had done this initially in my own project so that I could have consistency between the error messages throw by my application and in my unit tests. ie, to only have to define my exception messages in one place and at the time, the Resource file seemed like a sensible place to do this since I was already using it for various labels and strings (and since it made sense to add a reference to it in my test code to verify that those same labels showed in the appropriate places).
At one point I had considered (and tested) using try/catch blocks to avoid the requirement of a constant by the ExpectedException attribute, but this seemed like it would lead to quite a lot of extra code if applied on a large scale.
In the end, the solution that I settled on was to create a static class in my Resource library and store my exception messages in that. This way there's no need to internationalize them (which I'll agree doesn't make sense) and they're made accessible anytime that a resource string would be accessible since they're in the same namespace. (This fits with my desire not to make verifying the exception text a complex process.)
My test code then simply boils down to (pardon the mangling...):
[Test,
ExpectedException(typeof(System.ArgumentException),
ExpectedException=ProductExceptionMessages.DuplicateProductName)]
public void TestCreateDuplicateProduct()
{
_repository.CreateProduct("TestCreateDuplicateProduct");
_repository.CreateProduct("TestCreateDuplicateProduct");
}

Resources