How constructor calling occurs in case of c# custom exception handling? - c#

Here's is my program
class Program
{
static void Main(string[] args)
{
throw new UserAlreadyLoggedInException("Hello");
}
}
public class UserAlreadyLoggedInException : Exception
{
public UserAlreadyLoggedInException(string message) : base(message)
{
Console.WriteLine("Here");
}
}
Now, I know that base class constructor runs before derived class constructor. But when I run the above code the output comes out to be
Here
Unhandled Exception:Testing.UserAlreadyLoggedInException:Hello.
How come "Here" is printed before Unhandled.....?

You first have to create the exception, before you can be thrown.
Creation of the exception instance initiated by new UserAlreadyLoggedInException;
UserAlreadyLoggedInException constructor called;
Call to Console.WriteLine inside constructor;
Constructor done;
Throwing of the newly created exception instance;
The exception isn't handled, thus the application error handler writes the error to the console.

Why don't you try this:
static class Program
{
static void Main()
{
throw new UserAlreadyLoggedInException("Hello");
}
}
class LoginException : Exception
{
public LoginException(string message) : base(message)
{
Console.WriteLine("least derived class");
}
}
class UserAlreadyLoggedInException : LoginException
{
public UserAlreadyLoggedInException(string message) : base(message)
{
Console.WriteLine("most derived class");
}
}
You can also try writing your Main method like this:
static void Main()
{
var ualie = new UserAlreadyLoggedInException("Hello");
Console.WriteLine("nothing bad has happened yet; nothing thrown yet");
throw ualie;
}
So constructing an Exception instance with the new keyword does not "raise" or "throw" an exception. You need throw for that. The throw statement works by first evaluating the expression that comes after the throw keyword. The result of that evaluation will be a reference to an exception instance. After evaluating the expression, throw "throws" the exception referred by the value of the expression.
Your misunderstanding is that the Exception "explodes" as soon as the instance constructor to System.Exception runs. That is not the case.

If you add a try/catch of your own the program flow becomes more apparent. Note that Exception's constructor does not write anything it just stores the message string for later use.
class Program
{
static void Main(string[] args)
{
try
{
throw new UserAlreadyLoggedInException("Hello");
}
catch (Exception e)
{
Console.WriteLine("My handled exception: {0}", e.Message);
}
}
}
public class UserAlreadyLoggedInException : Exception
{
public UserAlreadyLoggedInException(string message) : base(message)
{
Console.WriteLine("Here");
}
}

The exception is printed to the console after it has been instantiated and thrown.
The instantiation prints "Here", then the runtime catches it and prints the "Unhandled Exception:" ToString() representation.

Related

C# Exception Listener

C# Question. Arbitrary class Class has method Foo(), a method which can throw an exception. Is there some way to add a private callback mechanism bar() to Class, such that if Foo() throws an exception, bar() execution will be triggered before the throw keeps going up the chain? If that can't happen, what about after the exception is caught?
-- Edit --
Since some of the initial comments are "this is confusing what are you doing dude" I'll address it further.
The reason I would like an exception listener is because I have some publicly readable boolean state about class Class, which I want to be set to true whenever an exception has been thrown. Since there could be potentially multiple functions within Class which throw exceptions, I don't want to do the boiler plate work of setting hasError to true each time an exception is thrown. Automate, baby.
So our interface, and main function are:
public interface IObjectProvider
{
IEnumerable<object> Allobjects { get; }
}
public interface IContext
{
delegate bool ContextIsStillValid(object o);
delegate void Run(object o);
}
// main program
public static void Main() {
IContext context = initcontext(...);
IObjectProvider objectProvider = initobjectprovider(...);
// ...program executes for awhile...
foreach(var obj in objectProvider.AllObjects)
{
if(context.ContextIsStillValid(obj))
{
try
{
context.Run(obj);
}
catch(Exception e)
{
// log the error
}
}
}
}
In the above code snippet, we specify some IContext which will 'Run' using some object, if and only if that IContext first successfully passes a 'Validation' check using that same object. Fine. Now, a common variation of implementation for IContext is the following (take my word, it is):
public class Class : IContext {
private bool _hasError = false;
// so our validation check is implemented with an internal flag.
// how is it set?
public bool ContextIsStillValid = (o) => !_hasError;
public void Run =
(o) =>
{
string potentially_null_string = getstring(...);
if(potentially_null_string == null)
{
// our internal flag is set upon the need to throw an exception
this._hasError = true;
throw new Exception("string was null at wrong time");
}
Global.DoSomethingWith(potentially_null_string.Split(',');
};
}
Here, we've demonstrated a common implementation of IContext, such that once the Run method throws a single Exception, the Run method should become unreachable due to IsContextStillValid subsequently always returning false.
Now imagine that there are other Exception-throwing calls within our implementation of Run(object). The problem is that every time we want to throw a new exception, we have to duplicate code to the effect of _hasError = true; throw new Exception(...);. Ideally, an exception listener would resolve this issue for us, and I am curious if any of you know how to implement one.
Hope that helps.
public class MyClass
{
public void Foo()
{
try
{
//Execute some code that might fail
}
catch
{
bar();
throw;
}
}
private void bar()
{
//do something before throwing
}
}

Can I overload the throw keyword?

I want to overload the throw keyword to catch a class which inherits from Exception and to have it do some logging and other stuff before the actual throw. Is this possible? Or do I have to use a regular function?
I've tried:
public class cSilException : Exception
{
private string m_strMsg;
public override void throw(cSilException ex)
{
}
...
...
}
Register the event AppDomain.FirstChanceException. There you get all exceptions before the are actually thrown. In the event handler you can check for your exception and do the required logging.
No magic and no bad design.
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
DoBadThings();
}
private static void DoBadThings()
{
DoOneLevelBelow();
}
private static void DoOneLevelBelow()
{
for(int i=0;i<10;i++)
{
try
{
if (i == 5)
{
var invalidCast = (string)((object)i);
}
else
{
throw new InvalidTimeZoneException();
}
}
catch
{
}
}
}
static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
if( e.Exception is InvalidCastException)
{
LogInvalidCast((InvalidCastException)e.Exception);
}
}
private static void LogInvalidCast(InvalidCastException invalidCastException)
{
Console.WriteLine("Got Invalid cast: {0}", invalidCastException);
}
This will lead to:
Got invalid cast: System.InvalidCastException: The object of the type
"System.Int32" cannot be converted to "System.String". at
ThrowTest.Program.DoOneLevelBelow() in
d:\Media\Blog\ThrowTest\Program.cs:line 31.
Please note since you are getting the exception before the stack is unwound you will see only the method where it did happen but not the calling methods since the stack was not unwound yet.
If you want the complete call stack you can use Environment.StackTrace to get all stack frames.
What you want to do is add a constructor to your exception and do whatever you need to do within that constructor.
public class cSilException : Exception
{
//constructor
public cSilException()
{
// do stuff here
}
}
Your notion of "overloading the throw keyword" was quite, er, how to put it, psychedelic.
Of course, as many have pointed out, it is best to avoid doing this if your intention is to do things such as logging. Alois Kraus has posted another answer with a very good suggestion.
I wouldn't recommend logging anything inside the exception's constructor since it violates the single responsibility principle and is considered a bad design. Also, the fact that an exception was created doesn't necessarily mean it has been thrown, and besides, exceptions can be caught and rethrown - these things may lead to incorrect logging messages.
Instead, you can use an application-wide exception handler which will handle exceptions according to your predefined policy. For example, you can have a look at the Enterprise Library Exception Handling Block and specifically this section.
You can't overload throw it is an integral part of the language (not a member of a class)
If you want to handle a specific Exception you should catch that exception:
try
{
// your code, which throws some exceptions
}
catch(cSilException csEx)
{
// handle csEx
throw; // rethrow this exception
}
catch(Exception ex)
{
// handle all other exceptions
}
This code catches the special exception cSilExceptionin a different code block than all other exceptions.
Look for methods and members of Exception class. You can define constructor for cSilException like this
public cSilException(string message)
{
Message = message;
}
and than in catch (cSilException ex) do Console.WriteLine(ex.Message);

Getting actual type from an exception thrown in base class

I have a series of classes in my application set up like follows:
abstract class Foo<TYPE> where TYPE : new()
{
public void Error()
{
List<TYPE> foo = null;
foo.Add(new TYPE());
}
}
class Bar : Foo<int>
{
}
When the call to Bar.Error() throws an exception, the stack trace simply reports it as being in Foo'1.Error(). I know exactly why it does that, but I need to know that it was a Bar object actually throwing the error. How can I derive that from the Exception object that gets thrown?
You can't, just from an exception you don't control. There's no indication in the exception what instance happened to have a method executing when the exception was generated.
I would suggest using a debugger (so that you can break if the exception is thrown) and/or using more diagnostic logging. (For example, log the type of this at the start of the method.)
Original answer, when the method itself directly threw the exception
(Keeping this for posterity - it might be useful to others.)
You could use the Source property, or perhaps the Data property to record the name of the type or the instance. For example:
abstract class Foo<TYPE>
{
public void Error()
{
throw new Exception("Whoops") { Data = {{ "Instance", this }} };
}
}
... then use:
catch (Exception e)
{
var instance = e.Data["instance"];
// Use the instance
}
This is a pretty odd use, however. It may well be more appropriate to throw your own custom exception type which explicitly knows about the instance that generated it.
You could try writing a custom Exception type that has a Type property, something like
public class CustomException : Exception {
public Type ExceptionSourceType{get;set;}
}
abstract class Foo<TYPE>
{
public void Error()
{
var exception = new CustomException ("Whoops");
exception.ExceptionSourceType = this.GetType();
throw exception;
}
}
Then if you specifically catch those types of errors you can easily access the property
catch(CustomException ex){
var sourceType = ex.ExceptionSourceType;
}

What is the right way to handle (log) custom exceptions?

A situation where a method tries to log a custom exception (custom exception class as code sample) causes a problem:
[Serializable]
public class CustomException : Exception
{
public CustomException() { }
public CustomException(string message) : base(message) { }
public CustomException(string message, Exception inner) : base(message, inner) { }
protected CustomException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
Creating the exception:
CustomException ex = new CustomException("Here is a new custom exception! ");
LogError(ex);
Method logging the exceptions (custom and others!):
public static void LogError(Exception ex)
{
//Saving exception messages, inner exceptions etc
//...
}
In this case the ex.Stacktrace of the custom exception is null when logging it!
I believe the reason is that the logging method (which tries to be a general purpose method) takes a Exception object as parameter rather than CustomException (?). What is the correct way to create a logging method, as overloading it with different exception types does seem a bit counterintuitive?
I believe the reason is that the logging method (which tries to be a general purpose method) takes a Exception object as parameter rather than CustomException (?)
Incorrect. It's null since you have not actually thrown the exception, just created it.
The stacktrace is generated as the exception travels up the callstack. Throwing the exception in the same method as you catch it will only create one stack trace item.
You can use:
public static void LogError<T>(T exception)
{
// Serialize the exception here and write to log
}
Note that you can simply use any object here in compbination with a human readable serialization format (i.e. formatted Json). Then you can simply log the serialized representation of the object, where all public fields/properties will be preserved.
Note that you'll also need throw/catch for stacktrace to be constructed for you.
Throw the CustomException instance before logging it. The runtime will fill in the stacktrace info
Log exceptions in catch block
Check logging level and log only message or full exception information.
For example, we use extension methods for TraceSource to log exceptions:
public static void TraceException(this TraceSource traceSource, Exception ex)
{
traceSource.TraceException(string.Empty, ex);
}
public static void TraceException(this TraceSource traceSource, string comment, Exception ex)
{
if (!string.IsNullOrWhiteSpace(comment))
comment += "\r\n";
traceSource.TraceEvent(TraceEventType.Error, (int)TraceEventType.Error,
comment + "ExceptionType: {0} \r\n ExceptionMessage: {1}", ex.GetType(), ex.Message);
if (traceSource.Switch.Level == SourceLevels.Verbose ||
traceSource.Switch.Level == SourceLevels.All)
{
traceSource.TraceEvent(TraceEventType.Verbose, 0, ex.ToString());
}
}
Usage:
catch(Exception ex)
{
_log.TraceException(ex);
}

Need to break after exception is handled

I have built an app in C#, where I have to break just after an exception is caught. I used return, but it returned to the module which called this module and continued execution. What should be done?
My code looks likes this:
class a
{
b bee=new b{};
bee.read(name);
bee.write(name);// don want this to get executed if exception is thrown
}
class b
{
read(string name)
{
try{}
catch
{
//caught;
//what should be put here so that it just stops after dialog
// box is shown without moving to the write method?
}
write(string name) {}
}
}
Your code sample is incorrect, but let's assume that you have a method with this code inside:
void M()
{
b bee=new b();
bee.read(name);
bee.write(name);// don want this to get executed if exception is thrown
}
If so, you have to catch exceptions in this method, not in read method. Like so:
void M()
{
try {
b bee=new b();
bee.read(name);
bee.write(name);// don want this to get executed if exception is thrown
}
catch(Exception e) {
// Proper error handling
}
}
In read method you should not suppress exceptions. Either don't catch them at all or rethrow them (or better yet, throw a new exception with the old one being its InnerExeption).
If you handle exceptions in method M this way, he line bee.write(name) won't be executed if an exception occurs somewhere inside bee.read(name).
Let the exception bubble up to the calling method:
class A {
public void Method() {
B bee = new B{};
try {
bee.Read(name);
bee.Write(name);
} catch(Exception ex) {
// handle exception if needed
}
}
}
class B {
public void Read(string name) {
try{
...
} catch(Exception ex) {
// handle exception if needed
throw;
}
}
public void Write(string name) {
}
}
Note: You should catch a more specific exception class if posible, instead of catching the base class Exception. The catch syntax without an excpetion parameter is obsolete.
you can do this as follows
class a
{
b bee = new b();
try
{
bee.read(name);
bee.write(name);
}
catch(Exception ex)
{
//handle error here
}
}
class b
{
//These are your method implementations without catching the exceptions in b
read
write
}
If you catch the exception in the method then you won't have any way of knowing the exceution state of the method without hangind some kind of error status off the method. Whether that is a boolean return or an error code that is accesible in b.
Why not have the read method return a value that means something to the caller? so the caller inspects the return from read and if it's (for example) null it doesn't call write. Alternatively your read method could return an enum value that tells the caller the condition with which the read method exited.
As another option your caller could implement an interface with a doNotProceed method, then pass itself to the read method. On exception read calls caller.doNotProceed, setting an internal variable within the caller object and this tells it to not proceed to write.
You have plenty of options
You can use return statement or re throw the error and put another a parent try catch , but its better you restructure your code.

Categories