I fully accept that this is essentially a repeat of question of
Catching custom exception in c#
That question is closed, so I hope to rephrase it as I am having the same problem.
I have a class that can be summarised thus..
[Serializable()]
public class DataFile : ISerializable
{
public DataFile()
{
// Data structures
}
public DataFile(SerializationInfo info, StreamingContext ctxt) : this()
{
if(true)
{
throw new VersionNotFoundException();
}
// Load data
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
// Save data
}
}
In my MainForm, I have a method that constains code equivilant to..
private DataFile Data;
private string CurrentFile = "C:\myfile.xyz";
private void LoadData()
{
try
{
using (Stream stream = File.Open(CurrentFile, FileMode.Open))
Data = (DataFile)new BinaryFormatter().Deserialize(stream);
}
catch (VersionNotFoundException e)
{
// never gets here
}
catch (Exception e)
{
// VersionNotFoundException gets caught here as an inner exception
}
}
My question(s)
Why would the VersionNotFoundException not get caught in the "catch (VersionNotFoundException e)" section (have I not added it to the top of the exception stack)? What am I doing wrong and how do I fix it? Why/how am I making an 'inner' exception and how do I stop it?
I was scratching my head with this and completely missed the comment.
// VersionNotFoundException gets caught here as an inner exception
You cannot catch inner exceptions like this, however you can use when in C#6 or later
try
{
}
catch (Exception e) when (e.InnerException is VersionNotFoundException e2)
{
Console.WriteLine(e2.Message);
}
catch (Exception e)
{
}
Demo here
Related
class Program
{
static void Main(string[] args)
{
try
{
using (var ss = new extest()) {
throw new Exception("Exception1");
}
}
catch(Exception ex)
{
System.Console.WriteLine(ex.Message);
}
}
}
class extest : IDisposable
{
public void Dispose()
{
throw new Exception("Exception2");
}
}
Run the codes result is "Exception2",
So I want to know how you can catch two exceptions, or just catch an Exception1.
My project has thousands of such using, which does not add try, but extest's Dispose is only one place, and I hope to know what exception has thrown before the Dispose.
Thanks
The problem in your example is that the second exception is thrown while the first exception is being handled. I.e. the using statement is effectively a try/finally pair, with the call to Dispose() in the finally block. So, the second exception supersedes the first one.
Having a Dispose() method that throws an exception is a very bad idea. So, the best solution here is to fix that. Don't throw an exception from a Dispose() method. But if you can't fix that for some reason and you want to see both, you need to make sure you're in a position to catch both. You can do this by adding another try/catch inside the using:
try
{
using (var ss = new extest()) {
try
{
throw new Exception("Exception1");
}
catch (Exception exInner)
{
System.Console.WriteLine(ex.Message);
throw;
}
}
}
catch(Exception ex)
{
System.Console.WriteLine(ex.Message);
}
The easiest way to handle this would be to rearrange your code:
static void Main(string[] args)
{
try
{
using (var ss = new extest())
{
try
{
CodeThatMightThrowAnException();
}
catch (Exception e)
{
// Process Exception here
}
}
}
catch(Exception ex)
{
System.Console.WriteLine(ex.Message);
}
}
Edit:
If the handling of the exceptions inside the using is always going to be the same, you could build a helper class that could make refactoring easier:
public class TryCatchHelper
{
public Exception Exception { get; private set; } = null;
public void Execute(Action action)
{
try
{
action()
}
catch (Exception e)
{
exception = e;
}
}
}
Then in your method:
static void Main(string[] args)
{
var helper = new TryCatchHelper();
try
{
using (var ss = new extest())
{
helper.Execute(() => {
// Your Code Block Here
});
}
}
catch(Exception ex)
{
// The Dispose threw an exception
}
if (helper.Exception != null)
{
// Handle the exception from the block here.
}
}
it's impossible to catch more than 1 exception.
when you throw Exception2 it should be catched in your catch clause. when you see "Exception2" it is printed by System.Console.WriteLine(ex.Message);. So, you can change the log in catch, or change the throwing exception message in Dispose.
reference added:
class Program
{
static void Main(string[] args)
{
try
{
using (var ss = new extest()) {
...
}
}
catch(Exception ex)
{
System.Console.WriteLine("extest error : " + ex.Message);
}
}
}
class extest : IDisposable
{
public void Dispose()
{
throw new Exception("Dispose failed: reason");
}
}
I have dll Scripting. In that dll I have class named Scripter. In Scripter class i call some methods which loads data from MySQL database (LoadTables()). In that functions which loads data from MySQL database exception could happen. I want to be able, later in my app where I use Scripting.dll, to do something like this:
Scrpter sc = new Scripter();
sc.OnError += ErrorOccured;
And want to have function ErrorOcured in my app which will be like:
private void ErrorOccured(Exception exception)
{...}
What I need to have in Scripter class, and how should I pass exception in catch block in LoadTables so I could later use ErrorOcured() to see what happend wrong?
As Picoh and Zoltan commented on your question, you can easily wrap method calls to Scripter methods in try/catch block. But, if you want to use event (with custom args), you can do something like this:
//your class
public class Scripter
{
public Scripter()
{
}
//public event with custom event args
public EventHandler<ScripterErrorEventArgs> OnError;
//just for test
public void RaiseError()
{
//error which is caught here
Exception ex = new Exception("something happened");
OnError?.Invoke(this, new ScripterErrorEventArgs(ex));
}
}
//class for custom event args. add your own other properties as needed
public class ScripterErrorEventArgs : EventArgs
{
public ScripterErrorEventArgs()
{
}
public ScripterErrorEventArgs(Exception ex)
{
this.Exception = ex;
}
public Exception Exception { get; set; }
}
//usage
public void someMethod()
{
Scripter s = new Scripter();
s.OnError += new EventHandler<ScripterErrorEventArgs>(LogError)
s.RaiseError();
}
private void LogError(object sender, ScripterErrorEventArgs e)
{
//your code here
}
You could try to modify your Scripter class like this
class Scripter
{
public event EventHandler<Exception> ErrorOcurred;
protected virtual void OnErrorOcurred(Exception e)=>ErrorOcurred?.Invoke(this, e);
public void ThrowsException()
{
try
{
throw new Exception("Throws exception");
}
catch (Exception ex)
{
OnErrorOcurred(ex);
}
}
}
This way you can subscribe to ErrorOcurred and receive notifications about exceptions. You must call OnErrorOcurred in every place you catch an exception
Hope this helps
I want to handle all exceptions to a Custom Exception Class. I don't want to raise Custom Exception in try block I want to every exception will catch by my custom Exception Class.
I don't want to do this:
private static void Main(string[] args)
{
try
{
Console.WriteLine("Exception");
throw new CustomException("Hello World");
}
catch (CustomException ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
I want this:
private static void Main(string[] args)
{
try
{
Console.WriteLine("Exception");
throw new Exception("Hello World");
}
catch (CustomException ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
public class CustomException : Exception
{
public CustomException()
{
}
public CustomException(string message) : base(message)
{
}
public CustomException(string message, Exception innerException)
: base(message, innerException)
{
}
protected CustomException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
Hope you get my question.
You cannot change the existing Exception classes.
But you can catch the exception and convert it to a CustomException:
try
{
try
{
// Do you thing.
}
catch(Exception e)
{
throw new CustomException("I catched this: " + e.Message, e);
}
}
catch(CustomException e)
{
// Do your exception handling here.
}
I don't know it this is what you want, but I think this is the closest you can do.
I am guessing you want to achieve this, beacause you want to treat every exception as if it was a CustomException. Well, why not just treat every exception in that way? Handle every exception the way you would handle your CustomException. If there are some Exceptions that you don't want to handle as a CustomException, then what you want to achieve is not what is in you question.
If you absolutely must treat everything as a CustomException, you could do something like this;
try
{
//Something that causes any form of exception
}
catch (Exception ex)
{
throw new CustomException(ex.Message); //Caught and handled in another place.
}
However, I don't think that's a sensible approach.
I'm trying to show a custom exception message while preserving the inner exception.
Here is my sample code:
public class Class1
{
public Class1()
{
try
{
throw new WebException("Initial Exception");
}
catch (WebException we)
{
throw new myException("Custom Message", we);
}
}
}
public class myException : WebException
{
public myException(string msg, WebException e) : base(msg, e) { }
}
When I run this code it shows me the custom message in the debugger:
yet still sends the innerexception message to the client:
What am I doing wrong here? How do I preserve the inner exception while showing my own custom message?
The way to customise the message the user sees is to provide a custom error page.
http://support.microsoft.com/kb/306355
I suspect it's because the ApplicationException isn't being effectively handled and the catch block throws an exception which is then being picked up as a base Exception. The debugger is then listing both exceptions.
I think this will give the behaviour you're after (I've written as a console app)
using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
myException exception;
try
{
throw new ApplicationException("Initial Exception");
}
catch (ApplicationException e)
{
exception = new myException("Custom Message", e);
}
catch (Exception e)
{
throw e;
}
if (exception != null)
{
throw exception;
}
}
}
}
public class myException : ApplicationException
{
public myException(string msg, ApplicationException e) : base(msg, e) { }
}
If you wrap a call to HttpResponse.End within a try catch block, the ThreadAbortException would automatically be re-raised. I assume this is the case even if you wrap the try catch block in a try catch block.
How can I accomplish the same thing? I do not have a real-world application for this.
namespace Program
{
class ReJoice
{
public void End() //This does not automatically re-raise the exception if caught.
{
throw new Exception();
}
}
class Program
{
static void Main(string[] args)
{
try
{
ReJoice x = new ReJoice();
x.End();
}
catch (Exception e) {}
}
}
}
You can't change ordinary exceptions to have this behaviour. ThreadAbortException has special support for this that you can't implement yourself in C#.
ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block.
It's as simple as using the plain throw statement.
throw;
in the relevant catch block. Note that this is advantageous over doing throw e; because it preserves the call stack at the point of the exception.
Of course, this isn't automated in perhaps the sense you want, but unfortunately that is not possible. This is pretty much the best solution you'll get, and pretty simple still I think. ThreadAbortException is special in the CLR because it is almost inherent in thread management.
In the case of your program, you'd have something like:
namespace Program
{
class ReJoice
{
public void End()
{
throw new Exception();
}
}
class Program
{
static void Main(string[] args)
{
try
{
ReJoice x = new ReJoice();
x.End();
}
catch (Exception e)
{
throw;
}
}
}
}
You mean like this?
namespace Program
{
class ReJoice
{
public void End() //This does not automatically re-raise the exception if caught.
{
throw new Exception();
}
}
class Program
{
static void Main(string[] args)
{
try
{
ReJoice x = new ReJoice();
x.End();
}
catch (Exception e) {
throw e;
}
}
}
}
Edit: It doesn't re-raise the exception because the meaning of "catch" is to handle the exception. It is up to you as the caller of x.End() what you want to do when an exception occurs. By catching the exception and doing nothing you are saying that you want to ignore the exception. Within the catch block you can display a message box, or log the error, kill the application entirely, or rethrow the error with additional information by wrapping the exception:
throw new Exception("New message", e);