Can I overload the throw keyword? - c#

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);

Related

Is it possible to wrap each test execution in XUnit?

I have an exception being thrown by multiple tests that contain some useful information. By default the failed unit test log does not contain that information since it is a property of a custom exception.
I can do this:
try
{
// Run code that casts MyException
}
catch (MyException e)
{
// Extra logging for e.SomeProperty
throw;
}
But then I will have to do this for each and every test. Is there somewhere I can do this for all of the tests of a test class? Kind of like a middleware in Asp.Net.
Or some alternative way to handle exception before XUnit.
If MyException is a type you define, you may want to consider changing Exception.Message to be a concatenation of what the user puts in, and the useful information, since generally you want to make the Message be as helpful to you as possible.
public class MyException : Exception
{
public MyException(string message)
: base($"{message}: {SomeProperty}") { }
// other constructors...
public required object SomeProperty { get; init; }
}
If however you cannot or don't want to, you could also have a helper function for your tests that uses a callback within a try-catch and rethrow the exception with more appropriate information. Exceptions can wrap inside other exceptions which allows each exception to be shown.
static void Do(Action act)
{
try
{
act();
}
catch (MyException my)
{
throw new($"something something foobar: {my.SomeProperty}", my);
}
}
(Bare in mind some linters will tell you throwing a bare Exception is bad, but for tests it shouldn't matter.)
You can finally use it in your tests like so:
[Fact]
void Foo() => Do(() =>
{
// your function goes here!
// you can simply throw the exception to test out how it'll look like
throw new MyException("yay") { SomeProperty = "context value" };
});

Catch an exception from an instance created with Activator.CreateInstance(type)

I have a C# application that can load other dlls with Activator.CreateInstance(type), that implement a given interface (plugins).
Now I want to catch all exceptions thrown from that new instance in it's own exception handler (because I cannot be sure that every exception is handled by the plugin properly) to present a message like:
Plugin [PluginName] caused the following error: [Exception.Message]
I can subscribe to the AppDomain.CurrentDomain.UnhandledException event, but this catches all exceptions and not only the ones caused by a certain plugin and I also can't see [that the|what] plugin caused the exception.
Is it possible to assign a exception handler to the created instance?
Thanks in advance,
Frank
I'm not sure I understand your exact scenario, but a solution could be creating a wrapper class around the plugin object that takes care of making sure all potential exceptions are handled correctly:
public interface IPluginObject
{
void Foo();
IBlah Bar();
...
}
public Wrapper<T>: IPluginObject where T: IPluginObject
{
private readonly T inner;
public Wrapper(IPlugin obj) { inner = obj; }
public void Foo()
{
try { inner.Foo() }
catch ....
finally ...
}
public IBlah Bar()
{
try { return inner.Bar(); }
catch ...
finally ...
}
}
Cumbersome? Yes, but you do get the benefit of knowing exactly what plugin is being troublesome.

C# exceptions and code breaking

I have a method called TryMe which has try catch block and catches his exceptions.
I call him from another class, but when an exception occurs it doesn't stop the code execution.
Example:
public void TryMe()
{
try
{
SomeMethod();
}
catch(Exception exception){
MessageBox.Show(exception.Message);
}
}
//Method calling
Actions CAactions = new Actions();
CActions.TryMe();
///////////////////////////////////
//If exception is handled it should stop to here.
this.Hide();
FormActions FormActions = new FormActions();
The method definition is in class file. The method calling is in the windows form.
The problem is that it just shows the messagebox and the code execution continues.
I want to stop the code after the exception catching and not hiding the form. If everything is okay it should hide it.
Maybe my conceptions is wrong?
The easiest fix would be to change your funcion to return true/false depending on whether it succeeded or not (i.e. only hide the form if the TryMe method didn't get an error):
public bool TryMe()
{
try
{
SomeMethod();
return true;
}
catch (Exception exception)
{
// log exception
return false;
}
}
and call it like this:
if (CActions.TryMe())
{
this.Hide();
}
Another option would be to re throw the exception after showing the message, and have the calling code handle it in a try catch:
public void TryMe()
{
try
{
SomeMethod();
}
catch (Exception exception)
{
// log exception?
throw;
}
}
calling code:
try
{
CActions.TryMe();
this.Hide();
}
catch (Exception ex)
{
// error handling
}
You should avoid calling MessageBox.Show() anywhere, but on UI side of your application (e.g. your Form). It is considered a bad practice. So i would modify NDJ's answer:
public bool TryMe()
{
try
{
SomeMethod();
return true;
}
catch (Exception exception)
{
//insert some logging here, if YOU need the callstack of your exception
return false;
}
}
if (CActions.TryMe())
{
this.Hide();
}
else
{
MessageBox.Show(...); //insert some meaningful message, useful to END-USER here, not some "Null refrence exception!!11" message, which no one but you will understand
}
Another option is delegate control flow to a caller, so :
public void TryMe()
{
try
{
SomeMethod();
}
catch(Exception exception){
throw;
}
}
and use it like
Actions CAactions = new Actions();
try {
CActions.TryMe();
//continue, all ok.
}
catch(Excepiton ex) {
//hide a form, exception happens inside a method
}
as your code states, the Exception is being caught and it's Message property passed to a MessageBox. That means that, in no way, your code is being interrupted or the Exception given the opportunity to bubble up.
On a side note: it's considered somewhat bad practice to display a MessageBox in a class try/catch (or any other method for that matter). The reason for this is obvious: it makes your class dependent on being used in a graphical application environment and that goes against class reusability. It's better to propagate the Exception along a method return type that any type of application could handle, e.g. a string containing the Message and/or the InnerException text.
You could then do e.g.
string methodResult = myObject.MyMethod();
if(String.IsNullOrEmpty(myMethodResult)) //... everything worked out ok
...
else //well then at least you have an error message to work with

Design Patterns in Exception Handling

I am actually writing a library class which could be used by multiple classes. I am simplying the example so as to make a point. Lets say I have three classes: A, B and C:
public class B
{
public static string B_Method()
{
string bstr = String.Empty;
try
{
//Do Something
}
catch
{
//Do Something
}
return bstr;
}
B is the library class that I am writing. Now there are lets say two other classes say A and C:
public class A
{
public void A_Method()
{
string astr = B.B_Method();
}
}
public class C
{
public void C_Method()
{
string cstr = B.B_Method();
}
}
The question is regarding the exception handling. I want the respective method of the two classes A and B to handle the exception occuring in B_Method in their own different ways.
I looked for framework design pattern, but felt that was not useful.
The approach that I usually follow is this:
If my method can do something useful with the exception, I catch it and do that.
If not, I don't catch it and leave it up to calling code to deal with it.
The only places where I would put a "catch all" block, is at entry points in UI code (such as event handlers for button clicks and such), since not catching exceptions there might take the process down.
This also means that exception clauses should catch the specific exceptions that you can handle.
One approach that I sometimes see is to catch the exception, wrap it in a new exception type and throw that. While that offers you some traceability, I also feel that it removes some options in the exception handling in calling code, such as having specific catch clauses for different scenarios. In these cases you will instead need to have if-clauses inspecting the inner exception with is less readable in my eyes.
B is the library class that I am writing.
If you have control over B code, B should rethrow the exception caught:
public class B
{
public static string B_Method()
{
string bstr = String.Empty;
try
{
// Do Something
}
catch(Exception e)
{
// Do Something (Log the exception details)
throw;
}
return bstr;
}
}
I want the respective method of the two classes A and B to handle the exception occuring in B_Method in their own different ways.
Now, B can log the exception and A and C can handle the rethrown exception is their own way.
You can rethrow or just let throw the exception in B_Method and catch it in A and C classes.
public class A
{
public void A_Method()
{
try
{
string astr = B.B_Method();
}
catch(Exception ex)
{
//Handle it in A way
}
}
public class C
{
public void C_Method()
{
try
{
string astr = B.B_Method();
}
catch(Exception ex)
{
//Handle it in C way
}
}
I think Design Patterns don't really apply here.. It's just OO programming.
remove the try and catch block from class b
public static string B_Method()throws Exception{
boolean success=compute();
if(!success){
throw new Exception("an error occured");
}
}
private static boolean compute(){
return false;
}

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