Ignore ThreadAbortException when logging exceptions - asp.net

What's the correct way of ignoring ThreadAbortException when logging exceptions?
Is it safe to just catch it in an empty catch block to make it disappear?

If you need to stop a ThreadAbortException propogating further up the call stack, you can call Thread.ResetAbort. So try something like:
try
{
// some code
}
catch (ThreadAbortException ex)
{
// do some logging
Thread.ResetAbort();
}
As for "correct" - that depends on your usage scenario. I'd generally be cautious about catching these unless you understand exactly why it has been raised. In escence it is a "stop now, quickly, and drop what you are doing" signal. Resetting it and going on to do further processing should be done with caution.

Employ two catch blocks: one for ThreadAbortException and one for the rest, for example:
void MainLoop()
{ bool workdone;
try
{ while( IsWorking ) // cross-thread volatile variable
{ workdone = Process();
if( !workdone )
{ Thread.Sleep( 500 ); }
}
}
catch( ThreadAbortException )
{ // Forced termination. Exit silently.
}
catch (Exception e)
{ LogError( e ); }
}

It is safe to catch it in a separate catch block. As an alternative you can catch all Exceptions and then check if a given Exception e is ThreadAbortException
I leave this post just because of the comments. Obviously, I was not knowing much about that exception.

With newer .NET versions ignoring an exception can be simplified to
try
{ // ...
}
catch (Exception e) when (!(e is ThreadAbortException))
{ LogError( e );
}
But this might still not be enough. Some libraries tend to wrap all exceptions with their own exception. In this case it could happen that the ThreadAbortExceptiononly appears as InnerException. I would not call it best practice to wrap a ThreadAbortException but it is real world.
To come around this I recommend an extension:
public static bool IsThreadAbort(this Exception ex)
{
while (ex != null)
{
if (ex is ThreadAbortException)
return true;
ex = ex.InnerException;
}
return false;
}
Now you can check with:
catch (Exception e) when (!e.IsThreadAbort())
{ LogError( e );
}

Related

How to make a method transactional in micronaut

I am using micronaut with sqlite db in my appliation and service class method looks like this:-
private void loadListIntoDb(Stream<EmpDto> lines) {
try {
empRepository.deleteAll();
lines.forEach(empRepository::saveEmpList);
} catch (Exception ex) {
throw new RuntimeException("error while loading file into db", ex);
}
}
What I want is if saveEmpList get failed, all the deleted data by deleteAll method should also get reverted back.
I have tried like this to test but it didn't rolled back the deleted items:
#Transactional
private void loadListIntoDb(Stream<EmpDto> lines) {
try {
empRepository.deleteAll();
throw new Exception("test exception");
} catch (Exception ex) {
throw new RuntimeException("error while loading file into db", ex);
}
}
Is there anything that I am missing.
Regards,
Finally resolved it. We can't make a private method transactional in Micronaut. We need to make the method as public.

Should i rethrow an interrupt when catching an InterruptedException in the catch block when doing a KafkaTemplate.send?

To send a record to a topic using KafkaTemplate which is configured as a bean like so:
#Bean
public KafkaTemplate<Object, Object> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
, one would do:
#Autowired
private KafkaTemplate<Object, Object> kafkaTemplate;
...
SendResult<Object, Object> sendResult = kafkaTemplate.send(topic, object).get();
and would catch the InterruptedException & ExecutionException by wrapping the above in a try/catch block like so
try {
SendResult<Object, Object> sendResult = kafkaTemplate.send(topic, object).get();
if (sendResult.getRecordMetadata() != null && sendResult.getRecordMetadata().hasOffset()) {
//some code
} else {
//some code
}
} catch (InterruptedException | ExecutionException e) {
logger.error("An error has occurred: ", e);
}
Recently, i have learnt that the best practice when an interrupted exception has occurred would be to re-throw it in the catch block like so:
} catch (InterruptedException | ExecutionException e) {
logger.error("An error has occurred: ", e);
Thread.currentThread().interrupt();
}
(1) Is this recommended in the KafkaTemplate context? I would tend to think no, because all the examples i am seeing are without the interrupt being re-thrown.
(2) If yes, what is the benefit?
(3) Is there any downside if the interrupt is not re-thrown?
This is basic interrupt handling and has nothing to do with Kafka.
Thread.currentThread().interrupt();
Yes, that is the best practice.
You are not "rethrowing" the interrupt there, you are setting the interrupt bit so that, if a downstream interruptible operation is performed on the thread, it too will be interrupted.
There is a big downside if you don't set the interrupt bit. When a thread is interrupted, usually, the application wants the thread to exit what it's doing.
Consider:
public void method2() {
...
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// ignore
}
}
public void method1() throws InterruptedException {
...
method2();
System.out.println("method2 returned ok");
Thread.sleep(Long.MAX_VALUE);
}
The thread will hang and never exit because you "ate" the interrupt.
However, you should not do this in a multi-catch:
} catch (InterruptedException | ExecutionException e) {
logger.error("An error has occurred: ", e);
Thread.currentThread().interrupt();
}
This would set the interrupt bit with both exceptions, not just the InterruptedException.

Try-Catch error handiling in ASP.NET

I have one doubt regarding Try-Catch block.
Below is my code
private void PopulateDDL()
{
try
{
if (my condition)
{
code
}
else
{
throw new Exception(ErrorMessage);
}
}
catch (Exception ex)
{
logerror(ex);
}
}
Which Catch block will be executed if error for below code
else
{
throw new Exception(ErrorMessage);
}
From MSDN:
When an exception is thrown, the common language runtime (CLR) looks
for the catch statement that handles this exception. If the currently
executing method does not contain such a catch block, the CLR looks at
the method that called the current method, and so on up the call
stack. If no catch block is found, then the CLR displays an unhandled
exception message to the user and stops execution of the program.
The catch block you have defined:
catch (Exception ex)
{
RaiseWebError(ex);
}
will be executed first for the exception throw new Exception(ErrorMessage);
If RaiseWebError re-throws the exception this will then be handled by the next try-catch block found futher up the call stack (i.e. the parent method you refer to). But if RaiseWebError handles the exception in some way (perhaps by logging the exception) execution will continue after the first try-catch.

Do I need to use exception handling if I use ELMAH?

Do I need to wrap my code with try...catch statements if I use ELMAH?
I have the following code:
namespace ElmahTestApp.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
try
{
DateTime date = DateTime.Parse("asdasdasd");
}
catch (Exception ex)
{
}
return View();
}
}
}
The view shows up (as expected) however the exception does not get logged. Any suggestions? THanks in advance!
If you want your code to handle exceptions gracefully (eg, fallback to something else), you still need catch blocks.
Look at ErrorSignal. In your case, you'd do something like
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}

Exception Handling in classes and Code Behind with C#

I'm a little bit stuck with a asp.net project that i'm doing! I have got a class that is called from the code behind and many of its function have no return type ie, being void. How does one do exception handling then??? Also, if the function within the class does have a return type of, for instance, a dataset how would one then return an exception or indicate that an exception had occured? I have attached the following code from my class which is referenced from the code behind.
public void fnRecord(string []varList, string fnName)
{
try
{
String x;
StringBuilder SQLParameters = new StringBuilder();
SQLParameters.AppendLine("SELECT #{Function}(");
{
SQLParameters.Replace("#{Function}", fnName);
}
for (int i = 0; i < varList.Length; i++)
{
x = varList[i].ToString();
SQLParameters.Append("'" + x + "',");
}
SQLParameters.Remove((SQLParameters.Length - 1), 1);
SQLParameters.Append(")");
string SQLCMD = SQLParameters.ToString();
conn.Open();
NpgsqlCommand command = new NpgsqlCommand(SQLCMD, conn);
Object result = command.ExecuteScalar();
}
catch (NpgsqlException ne)
{
//return ne;
}
catch (Exception x)
{
//error code
}
finally
{
conn.Close();
}
}
Any help would be appreciated!
Thanks
Only catch the exceptions where you intend to handle them properly. If you want to reflect the errors in the UI, catch them at the UI. If you want to handle them and try to deal with the issue in the business logic, then catch them and handle them at that point.
By the way, your code is susceptable to SQL injection attacks. Best go learn something about parameterised queries.
You don't return exceptions. You throw them. That's the point of exceptions - you don't want exception handling cluttering your method signatures!
In your catch clauses, you don't actually do anything to handle the exceptions. Then you should not catch them at all, just let them bubble up to your code-behind, and catch them there - put a try-catch round the method call.
Alternatively, catch your SQL exceptions in your method, then throw a new exception with some sensible message, adding the SqlExceptions as the inner exception, like this
catch (NpgsqlException ne)
{
throw new Exception("Your explanatory message here", ne);
}
finally
{
...
}
Cool thanks for the answers... working with the obout library so have to try and work out their exception handling functions too.

Resources