ctx.commandFailed vs throwing in PersistentEntity - lagom

In the Auction Example I have seen both ctx.commandFailed(...) and throw SomeException(...). Is there a good reason to throw instead of using the API and is there a difference between the two?

Persistent entity command handlers and after persist callbacks are wrapped in try/catch blocks, if an exception is caught, it will pass that exception to ctx.commandFailed(...) for you.
There is a subtle difference between the two to be aware of. If you throw an exception, processing of the command will of course stop immediately. If however you pass an exception to ctx.commandFailed(...), that will send the exception back to the invoker of the command, however it won't stop processing. You could in theory go on to return some directives to persist events - which would be an odd thing to do. In practice what you need to do is return ctx.done after invoking ctx.commandFailed(...).
In general it's probably simpler and safer to simply throw the exception.

Related

when it is correct purpose of exceptions

I am studying OOP, and I did not understood the concept of exception.
What are the correct uses of exceptions?
Why use exceptions when you already know a possible exception?
For example, I have seen a code sample where the programmer needed to access a file, and had an exception in case the file does not exist. Something like "catch(fileDoesNotExist e)".
Why not use an if to verify before take the action? And use exception only for not known issues, for logging or error messages.
The idea behind the concept of exception was to decouple the error handling code from the "normal" behaviour flow control. That lets to manage/handle the exception further up the call stack.
Historically, with structured language, error handling code (file opening error,...) was mixed within the "business" application code. It was also painful to improve the code in order to manage new error codes.
What are the correct uses of exceptions?
If it is not normal that your file doesn't exist or cannot be opened => it is considered as an exceptional situation => exception => exception handler
Why use exceptions when you already know a possible exception?
To decouple the business application code from the error handling. That eases source code readibility and maintenance.
Exception:
Exception is that interrupt(break) the normal flow of the program.It's thrown at runtime.
Exception Handling
Exception Handling is a mechanism to handle runtime errors such as ClassNotFound, IO, SQL, Remote etc
In java there are mainly two types of exception that checked and unchecked.Other than Error is there
Hierarchy of Exception classes in Java
Why use exceptions when you already know a possible exception?
basically exception handling use to mainly,we assuming in that our particular code will occur some(NullPointerException,ArrayIndexOutOfBoundsException etc..)exception.If we not Handle that,program will break.Actually that Exception it may or may not will happen.But so we need to handle normal flow of the program it occurred or not.Otherwise after that particular code section not executing.

NServiceBus UnitOfWork to swallow certain exceptions and avoid message failure

I have an interesting use case where certain exception types mean "This message is no longer valid and should be ignored" but this code doesn't have any awareness of the Bus in order to call Bus.DoNotContinueDispatchingCurrentMessageToHandlers().
I loathe boilerplate code like try/catch blocks that need to be present in every single message handler. So I started implementing a UnitOfWork to handle and swallow the exception, but I can't find a way to tell the framework that "Yes, this code generated an exception, but forget about that and just complete the transaction."
Bus.DoNotContinueDispatchingCurrentMessageToHandlers() does not work. I tried having an ITransport injected and calling AbortHandlingCurrentMessage() but that caused the entire universe to blow up. Even stepping through the source code I seem to be at a loss.
Note that it very well may be that this is a horrible idea, because faking that there is no exception when there is in fact an exceptional case would cause the transaction to commit, causing who knows how many bad unknown side effects. So it would be preferable to have a method that still rolls back the transaction but discards the message. But I would be interested in a potential "Yes I know what I'm doing, commit the transaction regardless of the exception" option as well.
As of NServiceBus version 4.4 you can control this by injecting a behavior into our handler pipeline.
This let's you control which exceptions to mute.
class MyExceptionFilteringBehavior : IBehavior<HandlerInvocationContext>
{
public void Invoke(HandlerInvocationContext context, Action next)
{
try
{
//invoke the handler/rest of the pipeline
next();
}
//catch specific exceptions or
catch (Exception ex)
{
//modify this to your liking
if (ex.Message == "Lets filter on this text")
return;
throw;
}
}
There are several samples of how this works:
http://docs.particular.net/samples/pipeline/
That said I totally agree with Ramon that this trick should only be used if you can't change to design to avoid this.
A dirty solution would be having a unit of work test the exception, put the message id in a shared 'ignore' bag (concurrent dictionary in memory, db, what works for you) , let it fail so that everything is rolled back, in the retry have a generic message handler compare the message ID and let that call Bus.DoNotContinueDispatchingCurrentMessageToHandlers()
If you do not want to work with a unit of work then you could try to use the AppDomain.FirstChanceException.
I wouldn't advice any of these as good solution :-)
Why would you like to 'swallow' unhandled exceptions?
If you want to ignore an exception then you should catch these in the handler and then just return and log this.
What I'm more interested in is what about state? You maybe have already writen to a store. Shouldn't these writes be rolled back? If you swallow an exception the transaction commits.
It seems to me you are running in a kind of 'at least once delivery' environment. THen you need to store some kind of message id somewhere.
Or is it an action initiated by several actors based on a stale state? In that case you need to have first/last write wins construction that just ignores a command based on a stale item.
If you handl an event then swallowing a exception seems not correct. They usually say that you can ignore commands but that you always have to handle events.
Shouldn't this be part of validation? If you validate a command then you can decide to ignore it.

Is there a way to get the last thrown exception outside of a try/catch block?

Edit:
To all answerers and commenters: Please focus on providing the solution I request rather than offer ways to refactor it. The code provided below is a very condensed example for the sake of brevity. I've already stated below that this type of code exists in 20 or 30 places throughout the app and that I am choosing not to move/merge/refactor any of that code if a simpler solution exists.
Original Question:
First, here's brief run-down: We have an app that was developed by an offshore team. The purpose of this application is to run nightly maintenance on various database tables. It is a WinForms app, but it acts more like a console app as all it does is 1) execute a single method in Form1_Load and then 2) call End to shut down the program.
The problem is that the error email notification doesn't work, so I have been charged with the task of fixing it. Consider this code:
Try
'This inner Try/Catch is actually code in another method
Try
'Run some code here
Catch ex As Exception
'Errors are logged silently to text file here
End Try
Catch ex As Exception
'Code to email exception details is here
End Try
The problem is that an exception is thrown and handled in the inner Try/Catch. Because of this, there's no exception to be handled in the outer Try/Catch, hence why no email notification is being sent.
Someone might say to just add Throw ex in the inner Catch, but keep in mind that there are about 20 or 30 places in the code where exceptions are handled like this. The decision I am making is to just get it working for now and not undergo that kind of development effort. Therefore, I seek a way to somehow acquire the last exception thrown by the application. This way, I can add a Finally block to the outer Try/Catch and do something like this:
Finally
If Not Application.GetLastException() is Nothing Then
SendErrorEmail(Application.GetLastException())
End If
End Try
So if I understand this correctly, your application catches all exceptions and logs them silently to a file.
You want to change the behavior so that when the program ends you get the last exception thrown, if any, and send an email with that exception detail. But the last exception thrown isn't stored anywhere.
And you want to change this behavior without modifying the code that handles the exceptions.
That can't be done. How do you expect to change the program's behavior without changing the program's behavior? What you ask is impossible. (And, no, not even Yoda would be able to pull this particular X-wing out of the swamp.)
There is no runtime property that automatically saves the last exception thrown.
You will have to make some modification to the code that catches the exceptions. You say that the code takes this general format:
Try
'This inner Try/Catch is actually code in another method
Try
'Run some code here
Catch ex As Exception
'Errors are logged silently to text file here
End Try
Catch ex As Exception
'Code to email exception details is here
End Try
I take it that the problem is in the inner Catch block. Seems to me that if there's common code to log the errors to a text file, that code should be in a separate method. If it is, then modify that method to save the last exception in a property that can be accessed by your GetLastException method. If there isn't a common method that handles the exception logging then you'll have to make the change at every place.
The commenters are correct: A general "catch all exceptions" is almost always a bad idea. Especially when the "handling" consists of logging and continuing. When you catch some random exception, you have no idea what the state of your program is. It's very likely that the data is corrupt and the program's state is unstable. "Log and continue" just makes the problem worse, and can lead to all kinds of interesting side effects like data corruption, infinite loops, deadlock, etc.
Your best course of action here is to refactor the code. Actually, the best course would be to send it back to the offshore developers and tell them to do it right. But that's probably too much to ask.
I'm quite late to this party but you could try this rather ugly way of doing things.
Firstly extend the Application class by adding a LastException property and a GetLastException function, see here for details.
Secondly add a line to each of the inner Catch blocks and set the LastExcepotion property:
Application.LastException = ex
There you go, no need to refactor all that offshore code.

#MessageDriven transactions and redelivery semantics

What's the best way to accomplish the following?
#MessageDriven bean does some work on database
on failure, I want to roll back the DB transaction
but I also want the JMS message NOT to be redelivered, i.e., don't re-try.
I can think of a few ways that might work. Are there any others, and which is the best?
use #TransactionManagement(type=BEAN) and UserTransaction, and explicitly roll back after catching exception. e.g.:
catch (Exception e) {
e.printStackTrace();
utx.rollback();
}
Use container-managed transactions, specify #TransactionAttribute(value=NOT_SUPPORTED) on onMessage and then delegate DB activity to a separate method with #TransactionAttribute(value=REQUIRED).
Leave the transaction handling alone and re-configure the retry property in the server. I'm using Glassfish 3.1.1, and I'm not exactly sure how to set this.
Leave everything alone and explicitly check the message for re-delivery in the onMessage body, and exit out if re-delivered. (message.getJMSRedelivered()?)
What has worked well out there? Is there a standard/best-practice way for dealing with this?
Simplest and most portable approach is use #TransactionAttribute(value=NOT_SUPPORTED) on onMessage() as you state and to move the DB work to another bean with #TransactionAttribute(REQUIRES_NEW)
Be careful about the separate method approach as this will not work. In a JMS MDB the onMessage() method is the only method where #TransactionAttribute can be used.
Personally I never do any work in the MDB, but dispatch immediately to an (injected) session bean.
This bean then does the DB work. It either starts a new transaction, or I catch any exception from the bean and log it (but don't let it propogate, so no redelivery).
This also has the advantage that the business logic is easly reusable from other places.

NHibernate Error reporting advice

This is not so much a problem as advice on best practice really. I am writing an ASP.Net MVC application, and in my DAL i am using NHibernate, but what do you do if an exception is thrown in your DAL?
Do you catch the exception in the DAL, log the error and then re-throw the exception?
Do you not even attempt to catch exeptions at all and use the Application_Error() method in the global.asax as a generic catch all?
Do you catch the exception log it and return a bool to the controller indicating a success or failure, or do you do something completly different?
Leading on from this how then do you handle informing the users? Do you show a generic "Error Occured - please try again" type page or do you show a more informative error?
This is exactly one of those 'it depends' questions. This is what I do:
Handle all exceptions in Application_Error (or similar sink-like location)
If the exception is base for business logic - say cannot have duplicates, just catch it and act upon it.
If it is an infrastructure exception and there is a good chance you can fix it by retrying - handle it in DAL.
Propagating specific exception info to user has hardly any benefit because usually the user cannot do anything about it anyway. So a generic error message usually makes do.
All unexpected and selected expected exceptions need to be logged with as much info as possible. It is also advisable that you get email with the exception info.
Now specifically to NHibernate - if NH throws an exception it is advised that you close and discard the currently active ISession and just fail. Because the session might be in an unknown/inconsistent state and trying to resurrect it can do more harm than good.
Obviously depending on scale and type of your app and number of various systems/programmers/etc. involved you really might to handle the logging yourself.