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.
Related
I am trying to catch a concurrent modification exception in Firestore in Datastore mode with Objectify. I created a method and ran it 50 times in 1 second to try and catch the exception. I found that I can only catch the exception if I use a transaction.
Is there a way to catch the CME without a transaction?
This does not catch the exception when ran 50 times in 1 second (even though I can see in the logs the entity is not always updated due to the 1/sec write limit):
try {
Entity entity = ofy().load().type(Entity.class)
.filter("username", "username1")
.first()
.now();
entity.setName("username2")
ofy().save().entity(newEntity).now();
} catch (com.google.cloud.datastore.DatastoreException datastoreException) {
// Never catches anything
} catch (Exception e) {
// Never catches anything
}
This catches the exception when ran 50 times in 1 second:
try {
ofy().transact(new VoidWork() {
public void vrun() {
Entity entity = ofy().load().type(Entity.class)
.filter("username", "username1")
.first()
.now();
entity.setName("username2")
ofy().save().entity(newEntity).now();
}
}
});
} catch (com.google.cloud.datastore.DatastoreException datastoreException) {
// Catches this error: Aborted due to cross-transaction contention. This occurs when multiple transactions attempt to access the same data, requiring Firestore to abort at least one in order to enforce serializability.
} catch (Exception e) {
}
Without a transaction the write is concerned a blind write. A blind write writes the content of the write even if another write has happened between your read & your write.
You should not expect a concurrent modification exception without a transaction.
Almost everything works great except one form that doesn't save some data to Azure database and I can't catch any info about exception i.e exception instance is null when break point stop in exception of type MobileServiceLocalStoreException. I checked the initialization of the local store and there is no problem with it, so what could be the reason behind this exception.
public async Task<T> CreateItemAsync(T item)
{
try
{
await table.InsertAsync(item);
}
catch(MobileServiceLocalStoreException ex)
{ // here exception occurd
Debug.WriteLine(ex.Message);
}
catch(Exception ex)
{
}
return item;
}
My intention is to log an error(I am using Log4Net) when an exception is caught and redirect to a pretty looking page with some error message. I have a class that returns a Type T object , mostly a DataSet.
In my Catch statement I wrote this, it works but I am not sure if there's a more appropriate way of handling, can someone please advice. Thanks. Note that the throw cannot be omitted because the class has a return type.:
catch (Exception ex)
{
log.Error(ex);
HttpContext.Current.Response.Redirect("~/errorPage.aspx");
throw ex;
}
It depends upon how you want to handle error on the page, In general , unhandled exception should be bubbled up to application_error in gloabl.asax file to it generic.Here is one simple way to handle this error.
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
// Get the exception object.
Exception exc = Server.GetLastError();
// Handle HTTP errors
if (exc.GetType() == typeof(HttpException))
{
// The Complete Error Handling Example generates
// some errors using URLs with "NoCatch" in them;
// ignore these here to simulate what would happen
// if a global.asax handler were not implemented.
if (exc.Message.Contains("NoCatch") || exc.Message.Contains("maxUrlLength"))
return;
//Redirect HTTP errors to HttpError page
Server.Transfer("HttpErrorPage.aspx");
}
// For other kinds of errors give the user some information
// but stay on the default page
Response.Write("<h2>Global Page Error</h2>\n");
Response.Write(
"<p>" + exc.Message + "</p>\n");
Response.Write("Return to the <a href='Default.aspx'>" +
"Default Page</a>\n");
// Log the exception and notify system operators
ExceptionUtility.LogException(exc, "DefaultPage");
ExceptionUtility.NotifySystemOps(exc);
// Clear the error from the server
Server.ClearError();
}
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 );
}
I am consuming one webservice, while consuming there can different types expception might occur depeninding on various situation like.. network failur, invalid soap data or exception from serverside also might occur.
How can I differntiate between these different excpetion?
Because in my application, with these exceptions I need to update the various status Like: if network failure occurs Status will be "unable to connect webservice" so I can try after sometime later. If exception comes from Web server , no need to call/try again.
nRk
What about a try/catch block but with multiple catches for different exceptions? e.g.
try
{
// webservice invocation
}
catch (SoapException ex)
{
// Handle Soap exceptions
}
catch (IOException ex)
{
// Handle IOException
}
catch (Exception ex}
{
// Handler of last resort - any exception not specifically handled above
// will be caught here
}