I have some functions that throw exceptions. I want that the code block that catch them also throw exception based on the exception that throw but with more parameters like ID and Note. how can I do that?
If any one can give me even direction it will be good!
Thanks (sorry for my English...)
Example for what I want (I know is not valid code...)
catch (Exception e)
{
LogException l=e;
l.Note = "note...";
l.ID = 12;
throw l;
}
You would need to define your own exception (inherited from Exception) that had those extra properties. See here for the basic format a custom exception should take
https://msdn.microsoft.com/en-us/library/ms229064(v=vs.100).aspx
(Note that you should make the exception serializable.) you just add your extra properties.
Once you have created the exception class (LogException in your case) then your above code will work.
Try this.
try
{
//....kaboom
}
catch (Exception ex)
{
var newEX= new Exception("custom message", ex);
newEX.Data.Add("any key", "any obj");
throw newEX;
}
Related
I have a method for manage exception handling as below. The Question is that, in case that the typeof exception is our point, which approach is recommended? Using
catch (System.Exception ex) when(ex.GetType() ==typeof(ExcOneException)){...}
or
catch (ExcOneException ex) {...}
public T MyMethod<T>(Func<T> codeToExecute)
{
try
{
return codeToExecute.Invoke();
}
catch (System.Exception ex) when(ex.GetType() ==typeof(ExcOneException) )
{
throw new ExcOneException(ex.Message,ex);
}
catch (System.Exception ex)
{
throw new ExcTwoException(ex.Message, ex);
}
}
UPDATE: My solution has 3 projects, UI, Services and DataAccess. Each part has its own custom Exception-Handler class. Imagine that, the code in question is in service project. All codes should call this method for execution. If there is any run-time error with type of ExcOneException, it means the error is in service section, else, there should be an error in data access part; so, ExcTwoException should be thrown. This approach helps me in bubbling error up to UI level with details. What I didn't know, was that, in the case that we can use C# 6 properties, when I have filtering just on exception type, which approach is better, using catch-when or mentioning exception type as argument of catch?
Simplification & Readability:
You can filter with is, instead of typeof:
catch (Exception ex) when (ex is ExcOneException) { ... }
Chain multiple Exception types:
catch (Exception ex) when (ex is ExcOneException || ex is ExcTwoException) { ... }
Why would you ever consider that? You mention performance. Do you have any measurements that make you suspicious.
Exception filters are there for filtering exceptions that you can't catch by type, which is not your case.
In your code you are, also, not re-throwing the caught exception. You are throwing an new exception with the caught exception as an inner exception which is what you do when you want to wrap the caught exception with a more meaningful one.
If you intention is to re-throw, the correct code is:
catch (System.Exception ex)
{
throw;
}
catch (HttpAntiForgeryException e)
{
throw new HttpAntiForgeryException("Forgery Exception");
}
When I build the project, there is a warning said: The variable 'e' is declared but never used.
Is that because the e is not necessary?
Yes. You can just simply write
catch (HttpAntiForgeryException)
{
throw new HttpAntiForgeryException("Forgery Exception");
}
But, you are rethrowing same type of exception. You can also simply delete this catch block.
It is no necessary if you don't want to do anything with the exception, in your case you are throwing custom message so its fine to use like this :
catch
{
throw new HttpAntiForgeryException("Forgery Exception");
}
or like this :
// For specific exception
catch (HttpAntiForgeryException)
{
throw new HttpAntiForgeryException("Forgery Exception");
}
But you will not get any information regarding this exception, like error message, stack-Trace, inner exception etc.. I prefer you to handle the exception in Catch, Or properly log them for developer's reference
It's because You have not used the Variable e within any where of the catch block. You can easily catch that exception so you will get better understanding of the root cause of your exception than throwing a new exception.
catch (HttpAntiForgeryException e)
{
Console.WriteLine(e.Message); // Console.Writeline or whichever way you want
}
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.
catch (OracleException e)
{
Cursor.Current = Cursors.Default;
_instance = null;
if (e.ErrorCode == -2147483648) // {"ORA-01017: invalid username/password; logon denied"}
{
throw new Exception("Nepravilno ime uporabnika ali geslo");
}
else
{
throw new Exception("Ne morem se povezati na podatkovno bazo. Preveri povezavo!");
}
}
but i always get Unhandled exception. Why?
At the risk of stating the obvious... Because you're not catching the Exception you throw in your catch block? Or, perhaps, something else is being thrown in the try block that isn't an OracleException.
What are you expecting to happen?
Just to be totally clear (to make sure that we're on the same page), an exception that's thrown but never caught will result in an unhandled exception (by definition). Throwing an exception from within a catch block is identical to throwing it from anywhere else; there still needs to be a try-catch somewhere to catch it. For example, this exception will be caught:
try {
throw new Exception("Out of cheese error"); // Caught below
}
catch (Exception) { }
But this one results in a new exception being propogated:
try {
throw new Exception("Out of cheese error"); // Caught below
}
catch (Exception) {
throw new Exception("418: I'm a teapot"); // Never caught
}
And this code catches both exceptions:
try {
try {
throw new Exception("Out of cheese error"); // Caught in inner catch
}
catch (Exception) {
throw new Exception("418: I'm a teapot"); // Caught in outer catch
}
}
catch (Exception e) {
Console.WriteLine(e.Message); // "418: I'm a teapot"
}
Your code does not in anyway swallow an exception. All it does is catch one type of exception and throw another type of exception. If you have an unhandled exception before you write this code, you will still have one after you write it.
--UPDATE --
Referring to your comment to another answer, if you want to display a message and stop executing code then try:-
catch (OracleException e)
{
Cursor.Current = Cursors.Default;
_instance = null;
if (e.ErrorCode == -2147483648) // {"ORA-01017: invalid username/password; logon denied"}
{
MessageBox.Show("Nepravilno ime uporabnika ali geslo");
}
else
{
MessageBox.Show("Ne morem se povezati na podatkovno bazo. Preveri povezavo!");
}
// this exits the program - you can also take other appropriate action here
Environment.FailFast("Exiting because of blah blah blah");
}
I assume you call hierarchy look like this:
Main
|-YourMethod
try {}
catch (OracleException) {throw new Exception("blah blah")}
So you see, the OracleException which occured in YourMethod is being caught by catch block, but then you throw a new one which goes into Main, where nothing handles it. So you should add an exception handler on the previous level.
Also, do not hide the original OracleException, throw your exception this way throw new Exception("your message", e). This will preserve the call stack.
Because you're only handling the OracleException. Nothing is handling the Exception() you are throwing.
You're catching the OracleException which means you're prepared to handle it - what does handling it mean to you? Logging it and moving on? Setting some state and moving on? Surely, you don't want to pop up gui in a data access component right? If you're not prepared to handle it, let it bubble up and handle it at an outer layer.
You also shouldn't throw exceptions of type Exception. Create your own strongly typed exceptions so they can be handled, or, simply log and call throw; which rethrows the original.
If you throw a new type of exception ensure you're passing the original exception as the inner exception to ensure you're not hiding details.
I did a write up on some best practices with C# exceptions:
Trying to understand exceptions in C#
Hope that helps
While using this code
try
{
transfer.TransferData();
}
catch (SmoException smoex)
{
//Do something
}
catch (Exception ex)
{
//Do something else
}
The exception is always caught by the second catch statement.
Does someone know why this happens?
Thanks in Advance
Use this to determine what the exception you get actually is:
try
{
transfer.TransferData();
}
catch (Exception ex)
{
var theRealExceptionTypeName = ex.GetType().Name;
}
This happens because the exception is not an SmoException.
It is either an Exception or another exception type deriving from Exception, but not SmoException. SmoException would be caught by the first handler if it were truely an SmoException or a class deriving from SmoException. Hopefully that sentence isn't as confusing to read as it was to type!
Further reading on exceptions and exception handling:
http://msdn.microsoft.com/en-us/library/ms173160(v=vs.80).aspx
Documentation doesn't say what exceptions are thrown:
http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.transfer.transferdata.aspx