I'm building a wpf application with a database in entity framework code first.
I allow the user to delete items in database, but when item is linked to other data, an exception will be thrown.
This is what I had originally
try
{
//delete item
}
catch (Exception ex)
{
MessageBox.Show(ex.Message)
}
This is working, but the message displayed isn't so much user firendly. So I tried to create a custom exception
public class CustomException : Exception
{
public CustomException (string Message)
{
Message = "Item can't be deleted";
}
}
And I've modified my catch
catch (CustomException ex)
{
MessageBox.Show(ex.Message)
}
But this is not showing the messagebox with my message, but it's stopping my application for a DbUpdateException.
Is there a way to customize the message for this type of exception?
Modifying the catch won't change how the framework throws an exception. You should just catch the DbUpdateException and show a message that is appropriate:
catch (DbUpdateException ex)
{
MessageBox.Show("item can't be deleted");
}
Related
I'm not familiar with exception handling (not much of a developer).
How do I catch an exception when a database doesn't exist or is offline? Do I need to throw a new Exception? The following gets me the warning "Exception was unhandled by user code"
catch (Exception err)
{
if (err is OracleException)
{
//database does not exist?
ErrorMessage = err.Message;
throw new Exception(ErrorMessage);
}
else
{
ErrorMessage = err.Message;
con.Close();
throw new Exception(ErrorMessage);
}
The 'Catch' expression is used to handle the Exception. If you are throwing another Exception, it needs to be catched somewhere.
And C# allows you to catch more than one exceptions, so you can do this:
try
{
//TRY TO OPEN THE CONNECTION
}
catch (OracleException oraExcep)
{
//DO SOMETHING IF A OracleException
//ERROR IS HANDLED HERE
}
catch (Exception ex)
{
//DO SOMETHING ELSE
}
it is allowed to use custom exception, where the exception can be thrown like below.
try
{
int foo = int.Parse(token);
}
catch (FormatException ex)
{
//Assuming you added this constructor
throw new ParserException(
$"Failed to read {token} as number.",
FileName,
LineNumber,
ex);
}
But in a normal try catch block, it says , throwing exceptions will clear the stacktrace.
try
{
ForthCall();
}
catch (Exception ex)
{
throw ex;
}
So in custom exception,how it managed to use throw exception, without clear the stacktrace?
There are several ways this can be done.
As mentioned in this link In C#, how can I rethrow InnerException without losing stack trace?, you can use the ExceptionDispatchInfo Class
with code similar to
try
{
task.Wait();
}
catch(AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
Another way is to have your handler return a boolean, whether the exception was handled or not, so you can use this in your catch clause:
catch (Exception ex) {
if (!HandleException(ex)) {
throw;
}
}
where HandleException is your custom Exception handler. Gotten from this link: How to throw exception without resetting stack trace?
Whenever you use throw with an exception object, it fills in the stack trace at that point. (Compare to Java, which populates stack traces when an exception is constructed.)
If you use throw without an exception object, which you can only do in a catch clause, the caught exception object is re-throw without alteration.
I have a table in the database that has the users of the application. The user name is unique, so I have a unique constraint in the table.
I am doing probes and one is try to use the same user name for two users. When the error occurs, I catch the exception "Eception" and I can see that the catched exception is System.Data.Entity.Infraestructure.DbUpdateConcurrencyException and the inner exception is System.Data.OptimisticConcurrencyException.
Then I catch the DbUpdateConcurrencyException, the innter exception is the OptimisticConcurrencyException, so I try to catch this exception too.
If I try to catch the OptimisticConcurrencyException before the DbUpdateConcurrencyException, is not catch, is catch the DbUpdateConcurrencyException.
SO I don't know how I can to catch the SqlException, because I would like to catch the error of the Sql Server, to get the code.
Thanks.
You can't handle 'inner exceptions'. You need to inspect the actual exception thrown in your catch handler, and rethow if you can't handle it. Example:
try
{
}
catch (DbUpdateConcurrencyException ex)
{
if (CanHandleException(ex))
{
// do what you have to do to handle the exception
}
else
{
throw; // can't handle this exception - just let it bubble up
}
}
In the method CanHandleException you would write the logic that determines whether you can handle this exception and do something meaningful (perhaps retry the operation). You do this by inspecting the properties of the exception (message, InnerException, ...)
Have you tried:
try
{
}
catch (SqlException ex)
{
}
You can handle it use
var objContext = ((IObjectContextAdapter)ctx).ObjectContext;
var entry = dbUpdateConcurrencyException.Entries.Single();
if (entry.State == EntityState.Deleted)
{
entry.State = EntityState.Detached;
}
else
{
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
objContext.Refresh(RefreshMode.ClientWins,dbUpdateConcurrencyException.Entries.Select(e => e.Entity));
}
if I do this:
try
{
//code
}
catch (Exception)
{
throw;
}
Does the Exception go up with all its information?
The idea is to handle errors at the top of the app. There I'd execute some SQL sp to fill the admin's table so he's aware of exceptions.
I want to store Exception.Message and the source (method, function, whatever..) of the exception. But I don't know how to refer to "where" the exception happened. Is it Exception.Source? Exception.TargetSite?
Thanks.
The type of Exception will tell you what kind of exception it is (IndexOutOfRangeException, SqlException, etc) which you would react too accordingly:
try
{
//code
}
catch (SqlException ex)
{
// Handle code
}
catch (IndexOutOfRangeException ex)
{
// Handle code
}
catch (Exception ex)
{
// Handle code
}
As to where it is happening... you should be enclosing exception-prone areas with a try catch and not large code chunks. This way you will know where the exception derives from.
The Short answer is yes: just calling throw passes everthing regarding the exception up.
throw ex resets the stack trace (so your errors would appear to originate from HandleException)
throw doesn't - the original offender would be preserved.
(quoted from Mark Gravell)
I have an aspx page that, on a button click, creates an instance of a serviceRefernece object. In the code behind for my page I have the call wrapped in a try/catch.
try
{
var client = GetClient();
var request = new ActiveVerificationRequestDC();
var response = client.GetActiveVerification(request);
DoSomethingWithTheResponse(response);
}
catch (FaultException ex)
{
LogError(ex, MethodBase.GetCurrentMethod().Name);
throw;
}
catch (Exception ex)
{
var args = new[] { MethodBase.GetCurrentMethod().Name, ex.Message };
DisplayError(args);
}
The svc file that is referenced is using pretty much the same pattern. It is calling an internal client over net.tcp. The call is wrapped in a try/catch
try
{
var client = new InternalServiceClient();
var response = client.GetActiveVerification(request);
client.Close();
return response;
}
catch (FaultException fe)
{
LogError(MethodBase.GetCurrentMethod().Name, fe);
throw;
}
Here is my problem, how do I get errors here to bubble up to my UI catch statement? When I leave it like this, I get an unhandled exception error from visual studio. I have tried removing the throw which makes me specify a return value, and I return null. This makes the UI not work correctly. I have tried throw new Exception(fe.message) and I get the same problem with the unhandled exception. Basically my question is how can I accomplish what I need? What am I missing?
You need a separate try/catch block around your try/catch block. You have it such that you will catch a FaultException and any type of Exception, but your Exception block will not catch your throw from FaultException. So, just enclose this with another try/catch or handle it within both the FaultException catch and the Exception catch.
The reason could be the throwing of another exception in your second code snippet that isn't of the type FaultException; such an exception would pass as unhandled in this situation. Maybe you should add another catch block to your second code snippet that catches exceptions of the type Exception:
catch (FaultException fe)
{
LogError(MethodBase.GetCurrentMethod().Name, fe);
throw;
}
catch (Exception ex)
{
throw;
}
Is the FaultException you are re-throwing a generic type? Are the relevant classes detailed by any FaultContract attributes accessible to all assemblies in this execution stack?
Edit: In your first code snippet ...
catch (FaultException ex)
{
LogError(ex, MethodBase.GetCurrentMethod().Name);
throw;
}
If the unhandled error occurs on the throw statement of this handler, then #MCain is right.
I believe you have to throw in the catch block for the error to bubble up
try
{
}
catch (SqlException _SqlException)
{
//Log Error to file
throw;
}
catch (IOException _IOexception)
{
//Log Error to file
throw;
}
catch (Exception _exception)
{
//Log Error to file
throw;
}
This kind of a block will be in the calling method