how to differentiate among different exceptions of same class? - c#

how to check whether its is login info exception or a connection lost exception if the the exceptions are form the same class?
private bool checkFileExists(string absoluteRemoteLocation)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(absoluteRemoteLocation);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Timeout = timeOut;
request.Credentials = new NetworkCredential(this.username, this.password);
request.GetResponse();
return true;
}
catch(Exception e) //i want to check here
{
var g = e.ToString();
return false;
}
}

Use different catch block like this:
catch (System.TimeoutException e)
{
var g = e.ToString();
return false;
}
catch (System.Net.WebException e)
{
var g = e.ToString();
return false;
}

Use is keyword of C#.
<!-- language: C# -->
catch (Exception e) {
if (e is LoginInfoException) // do something
else if (e is ConnectionLostException) // do something else
}
For reference, check this link.

Isn't this what you want?
public class Program
{
public static void Main(string[] args)
{
try
{
throw new ConnectionLostException();
}
catch (Exception ex)
{
if (ex is LoginInfoException)
{
Console.WriteLine ("LoginInfoException");
}
else if (ex is ConnectionLostException)
{
Console.WriteLine ("ConnectionLostException");
}
}
}
}
public class LoginInfoException : WebException
{
public String Message { get; set; }
}
public class ConnectionLostException : WebException
{
public String Message { get; set; }
}

This is a simple example of a filter that will catch different exceptions. I don't know much about the hierarchy of exceptions you're dealing with, but this will allow you to filter what exceptions get caught where.
public class CatchExceptions
{
public void SomeMethod ()
{
try
{
//some stuff that throws exceptions
}
catch (WebException e) if (e is LoginInfoException)
{}
catch (WebException e) if (e is ConnectionLostException)
{}
}
}
Obviously you'll have to figure out what you can use to filter the exceptions like so; it appears that the two examples I used above are not concrete types. You may need to do some restructuring to figure out how to differentiate between the two.

Related

How to enforce each Inside method must have throw

Enforce each Inside method must have throw or enforce not use try catch block.
Below example InsideMethod2() is not implemted throw in this case when it's is calling in Main() method, should give some warning or error message saying that you must throw or should not use try catch block.
Example :
public void Main()
{
try
{
InsideMethod1();
InsideMethod2();
}
catch (System.Exception)
{
throw;
}
}
public int InsideMethod1()
{
try
{
// implementation here
}
catch (System.Exception)
{
// log
throw;
}
}
public int InsideMethod2()
{
// enforce throw or enforce not use try catch block
int a = 1, b = 0, c = 0;
try
{
c = a / b;
}
catch (System.Exception)
{
// enforce to throw
// log
}
return c;
}
Is it possible to enforce inside methods..?

Cannot catch custom exception thrown in MSScriptControl's Eval function

This is a MVCE of my problem.
I have this method using MSScriptControl to dynamically evaluate some formula.
public void DoCalculate()
{
try
{
var evaluator = new Evaluator();
IScriptControl ctrl = new ScriptControl();
ctrl.Language = "JavaScript";
ctrl.AddObject("Evaluator", evaluator, false);
var calcFunction = "Number(Evaluator.Divide(4,0))";
double rs = ctrl.Eval(calcFunction);
}
catch (CustomException cex)
{
// Handle CustomException.
}
catch (Exception ex)
{
// Handle general Exception.
}
}
This is the Evaluator class.
public class Evaluator
{
public double Divide(int a, int b)
{
if (b == 0)
{
throw new CustomException("Cannot divide by zero");
}
else
{
return a / b;
}
}
public void TestThrow()
{
throw new CustomException("This is a test");
}
}
And this is the CustomException class:
using System;
namespace Library
{
public class CustomException : Exception
{
public CustomException()
: base()
{
}
public CustomException(string message)
: base(message)
{
}
}
}
I expected that in this case a CustomException will be throw, and the first catch clause will be entered. However, I got an general Exception (I verified the exception type using GetType().Name) with the message "Cannot divide by zero" instead.
I did get the following error in Evaluator class though:
An exception of type 'Library.CustomException' occurred in XXX.dll but was not handled in user code
If I modify my DoCalculate() like this then I can catch a CustomException just fine:
public void DoCalculate()
{
try
{
var evaluator = new Evaluator();
evaluator.TestThrow();
}
catch (CustomException cex)
{
// Handle CustomException.
}
catch (Exception ex)
{
// Handle general Exception.
}
}
Does that mean it is impossible to define and throw my own exception from inside Eval function?
I'm using .NET 4.6.2 and Interop.MSScriptControl 1.0.0.0
This is the summary of the answer given in this link
COM methods report errors by returning HRESULTs; .NET methods report them by throwing exceptions. The runtime handles the transition between the two. Each exception class in the .NET Framework maps to an HRESULT. So in order to throw proper exception, Let me suggest the following.
var evaluator = new Evaluator();
IScriptControl ctrl = new MSScriptControl.ScriptControl { Language = "VBScript" };
ctrl.AddObject("Evaluator", new Evaluator(), true);
const string calcFunction = "Evaluator.Divide(4,0)";
try {
double rs = ctrl.Eval(calcFunction);
}
catch (DivideByZeroException ex) {//Actual DivideByZeroException from .Net
//How can you divide by zero?!?!
}
catch (Exception ex) {
//STUFF
}
public class Evaluator {
public double Divide(int a, int b) {
if (b == 0) {
throw new MyDivideByZeroException();
}
return a / b;
}
}
public class MyDivideByZeroException : Exception {
public MyDivideByZeroException() {
HResult = -2147352558;
}
}

Catch derived class Exceptions in base class with different methods and arguments

I'm trying to make something like base "exception handler" thing. So this base class will try-catch exceptions when any method (with any number of parameters) in derived class gets invoked. I'm not good in describing this with words, so here is the scenario:
public abstract BaseClass
{
Exception _ex;
public Exception LastKnownException
{
get
{
return this._ex;
}
}
//...
//what do I do here to assign the value of above property when some random exception occur in derived class?
//...
//The closest I can get...
public void RunMethod(Action method)
{
try
{
method.Invoke();
}
catch (Exception ex)
{
this._ex = ex;
}
}
}
public class DerivedClass : BaseClass
{
public void DoRandomMethod(int couldBeOfAnyTypeHere, bool andIndefiniteNumberOfThese)
{
bool result = false;
var someObject = new OtherClass(couldBeOfAnyTypeHere, out andIndefiniteNumberOfThese);
someObject.DoInternalWork(result); // <-- here is where I need the base class to take care if any exception should occur
}
public int AnotherMethod(int? id)
{
if (!id.HasValue)
id = Convert.ToInt32(Session["client_id"]);
var someOtherObject = new OtherClassB(id.Value);
return someOtherObject.CheckSomething(); // <-- and catch possible exceptions for this one too
}
//The closest I can get... (see base class implementation)
public List<RandomClass> GetSomeListBy(int id)
{
RunMethod(() =>
string[] whateverArgs = new[] { "is", "this", "even", "possible?" };
YetAnotherStaticClass.GetInstance().ExecuteErrorProneMethod(whateverArgs); // <-- Then when something breaks here, the LastKnownException will have something
);
}
}
public class TransactionController : Controller
{
public ActionResult ShowSomething()
{
var dc = new DerivedClass();
dc.DoRandomMethod(30, true);
if (dc.LastKnownException != null)
{
//optionally do something here
return RedirectToAction("BadRequest", "Error", new { ex = dc.LastKnownException });
}
else
{
return View();
}
}
}
EDIT: My simple approach will work, only, I don't want to have to wrap all methods with this lambda-driven RunMethod() method all the time -- I need the base class to somehow intercept any incoming exception and return the Exception object to the derived class without throwing the error.
Any ideas would be greatly appreciated. And thanks in advance!
I think you should consider using the event System.AppDomain.UnhandledException
This event will be raised whenever an exception occurs that is not handled.
As you don't clutter your code with the possibilities of exception, your code will be much better readable. Besides it would give derived classes the opportunity to catch exceptions if they expect ones, without interfering with your automatic exception catcher.
Your design is such, that if someone calls several functions of your derived class and then checks if there are any exceptions the caller wouldn't know which function caused the exception. I assume that your caller is not really interested in which function causes the exception. This is usually the case if you only want to log exception until someone investigates them.
If that is the case consider doing something like the following:
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
if (ex != null)
logger.LogException(ex);
// TODO: decide whether to continue or exit.
}
If you really want to do this only for your abstract base class
public abstract BaseClass
{
private List<Exception> unhandledExceptions = new List<Exception>();
protected BaseClass()
{
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
}
private void UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
if (ex != null)
this.UnhandledExceptions.Add(ex);
}
public List<Exception> LastKnownExceptions
{
get { return this.unhandledExceptions; }
}
I had a similar requirement for catching exceptions, but used a specific implementation (i.e. not an abstract class) to encapsulate the handling of errors.
Please note this takes in an argument for any expected exceptions (params Type[] catchableExceptionTypes), but of course you can modify to suit your own requirements.
public class ExceptionHandler
{
// exposes the last caught exception
public Exception CaughtException { get; private set; }
// allows a quick check to see if an exception was caught
// e.g. if (ExceptionHandler.HasCaughtException) {... do something...}
public bool HasCaughtException { get; private set; }
// perform an action and catch any expected exceptions
public void TryAction(Action action, params Type[] catchableExceptionTypes)
{
Reset();
try
{
action();
}
catch (Exception exception)
{
if (ExceptionIsCatchable(exception, catchableExceptionTypes))
{
return;
}
throw;
}
}
// perform a function and catch any expected exceptions
// if an exception is caught, this returns null
public T TryFunction<T>(Func<T> function, params Type[] catchableExceptionTypes) where T : class
{
Reset();
try
{
return function();
}
catch (Exception exception)
{
if (ExceptionIsCatchable(exception, catchableExceptionTypes))
{
return null;
}
throw;
}
}
bool ExceptionIsCatchable(Exception caughtException, params Type[] catchableExceptionTypes)
{
for (var i = 0; i < catchableExceptionTypes.Length; i++)
{
var catchableExceptionType = catchableExceptionTypes[i];
if (!IsAssignableFrom(caughtException, catchableExceptionType)) continue;
CaughtException = caughtException;
HasCaughtException = true;
return true;
}
return false;
}
static bool IsAssignableFrom(Exception exception, Type type)
{
if (exception.GetType() == type) return true;
var baseType = exception.GetType().BaseType;
while (baseType != null)
{
if (baseType == type) return true;
baseType = baseType.BaseType;
}
return false;
}
void Reset()
{
CaughtException = null;
HasCaughtException = false;
}
}

Is it possible to catch an exception you can't handle (in C#)?

I have a generic class that catches exceptions of T:
public abstract class ErrorHandlingOperationInterceptor<T> : OperationInterceptor where T : ApiException
{
private readonly Func<OperationResult> _resultFactory;
protected ErrorHandlingOperationInterceptor(Func<OperationResult> resultFactory)
{
_resultFactory = resultFactory;
}
public override Func<IEnumerable<OutputMember>> RewriteOperation(Func<IEnumerable<OutputMember>> operationBuilder)
{
return () =>
{
try
{
return operationBuilder();
}
catch (T ex)
{
var operationResult = _resultFactory();
operationResult.ResponseResource = new ApiErrorResource { Exception = ex };
return operationResult.AsOutput();
}
};
}
}
With subclasses for specific exceptions e.g.
public class BadRequestOperationInterceptor : ErrorHandlingOperationInterceptor<BadRequestException>
{
public BadRequestOperationInterceptor() : base(() => new OperationResult.BadRequest()) { }
}
This all seems to work perfectly. But, somehow, in the logs (once, not every time) is an InvalidCastException:
System.InvalidCastException: Unable to cast object of type 'ErrorHandling.Exceptions.ApiException' to type 'ErrorHandling.Exceptions.UnexpectedInternalServerErrorException'.
at OperationModel.Interceptors.ErrorHandlingOperationInterceptor`1.c__DisplayClass2.b__1() in c:\BuildAgent\work\da77ba20595a9d4\src\OperationModel\Interceptors\ErrorHandlingOperationInterceptor.cs:line 28
Line 28 is the catch.
What am I missing? Have I done something really dumb?
As smithy said, your T is of type ApiErrorResource. You are, some where in your code, attempting to create your ErrorHandlingOperationInterceptor with an Exception that is NOT derived from ApiErrorResource.
try
{
// throw Exception of some sort
}
catch (BadRequestException ex)
{
BadRequestOperationInterceptor broi = new BadRequestOperationInterceptor ();
}
catch (Exception ex)
{
// this is NOT right
BadRequestOperationInterceptor broi = new BadRequestOperationInterceptor ();
}

C# How to handle multiple exceptions which does all the same?

In my code I have a method with multiple catch statements, which perform all the same statement. I'm not sure this is the correct way to implement this. How would you do this?
public void LoadControl(ControlDestination controlDestination, string filename, object parameter)
{
try
{
// Get filename with extension
string file = GetControlFileName(filename);
// Check file exists
if (!File.Exists(file))
throw new FileNotFoundException();
// Load control from file
Control control = LoadControl(filename);
// Check control extends BaseForm
if (control is BaseForm)
{
// Set current application on user control
((BaseForm)control).CurrentApplication = this;
((BaseForm)control).Parameter = parameter;
// Set web user control id
control.ID = filename;
Panel currentPanel = null;
switch (controlDestination)
{
case ControlDestination.Base:
// Set current panel to Base Content
currentPanel = pnlBaseContent;
// Set control in viewstate
this.BaseControl = filename;
break;
case ControlDestination.Menu:
// Set current panel to Menu Content
currentPanel = pnlMenuContent;
// Set control in ViewState
this.MenuBaseControl = filename;
break;
}
currentPanel.Controls.Clear();
currentPanel.Controls.Add(control);
UpdateMenuBasePanel();
UpdateBasePanel();
}
else
{
throw new IncorrectInheritanceException();
}
}
catch (FileNotFoundException e)
{
HandleException(e);
}
catch (ArgumentNullException e)
{
HandleException(e);
}
catch (HttpException e)
{
HandleException(e);
}
catch (IncorrectInheritanceException e)
{
HandleException(e);
}
}
This is how HandleException looks like:
private void HandleException(Exception exception)
{
// Load error control which shows big red cross
LoadControl(ControlDestination.Menu, "~/Controls/Error.ascx", null);
// Store error in database
DHS.Core.DhsLogDatabase.WriteError(exception.ToString());
// Show error in errorbox on master
Master.ShowAjaxError(this, new CommandEventArgs("ajaxError", exception.ToString()));
}
You are doing it right (you should catch only the exceptions you are going to handle and there is no way to catch more than one exception type in one single catch block), but as an alternative, you can just catch(Exception ex), check the exception type, and if it is not one that you expect just throw it again, something like this:
var exceptionTypes=new Type[] {
typeof(FileNotFoundException),
typeof(ArgumentNullException),
//...add other types here
};
catch(Exception ex) {
if(exceptionTypes.Contains(ex.GetType()) {
HandleException(ex);
} else {
throw;
}
}
UPDATE: With C# 6 (coming together with Visual Studio 2015) you are able to do the following instead:
catch(Exception ex) when (exceptionTypes.Contains(ex.GetType()) {
HandleException(ex);
}
I'd refactor as follows:-
public class Sample
{
public void LoadControl( ControlDestination controlDestination, string filename, object parameter )
{
HandleExceptions( HandleException, () =>
{
//.... your code
} );
}
private void HandleExceptions( Action<Exception> handler, Action code )
{
try
{
code();
}
catch ( FileNotFoundException e )
{
handler( e );
}
catch ( ArgumentNullException e )
{
handler( e );
}
catch ( HttpException e )
{
handler( e );
}
catch ( IncorrectInheritanceException e )
{
handler( e );
}
}
private void HandleException( Exception exception )
{
// ....
}
}
If I was using VB.NET, I'd use exception filters to do series of catches. But as we're using C#, the approach you have is the most efficient one possible rather than doing
private void HandleExceptions( Action<Exception> handler, Action code )
{
try
{
code();
}
catch ( Exception e )
{
if ( e is FileNotFoundException
|| e is ArgumentNullException
|| e is HttpException
|| e is IncorrectInheritanceException )
handler( e );
else
throw;
}
}
You can use generics for a much nicer solution as long as you don't mind using Lambda's too. I am not a fan of switching on type. I have used this code a few times, I find it comes in especially handy for service proxies in which you want to handle a number of exceptions in the same way. As has been stated above its always best to catch the right type of exception where possible.
The code works by specifying the exceptions as generic type arguments to the handle function. These specific types are then caught but passed to a generic handler as the base class. I didn't add a HandleAndThrow but this can be added as desired. Also change naming to your liking.
public static void Handle<T>(Action action, Action<T> handler)
where T : Exception
{
try
{
action();
}
catch (T exception)
{
handler(exception);
}
}
public static void Handle<T1, T2>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
}
public static void Handle<T1, T2, T3>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
where T3 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
catch (T3 exception)
{
handler(exception);
}
}
public static void Handle<T1, T2, T3, T4>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
where T3 : Exception
where T4 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
catch (T3 exception)
{
handler(exception);
}
catch (T4 exception)
{
handler(exception);
}
}
}
public class Example
{
public void LoadControl()
{
Exceptions.Handle<FileNotFoundException, ArgumentNullException, NullReferenceException>(() => LoadControlCore(10), GenericExceptionHandler);
}
private void LoadControlCore(int myArguments)
{
//execute method as normal
}
public void GenericExceptionHandler(Exception e)
{
//do something
Debug.WriteLine(e.Message);
}
}
Write it like this:
try
{
// code that throws all sorts of exceptions
}
catch(Exception e)
{
HandleException(e);
}
edit: note that this is a direct answer to your question, not a comment on whether or not this is a recommended practice.
edit2: you can however test in your function if the type of e is a specific list of exceptions and if it's not, you can rethrow it. Exception handling performance is a non-issue since it's meant to be... exceptional in the first place.
I'm going to answer this is in a language-agnostic manner:
1. What you have done now is correct. Nothing wrong with it, except that it might get tedious if you do it many times.
2. Catch the most general form of exception that there is. Simply
catch(Exception e)
{
...
}
3. Maybe you want to only catch some exceptions, without catching all exceptions, which is what you would be doing if you just did #2.
Do what you did in #2, plus modify HandleException to only handle certain types of exceptions. This way you will only ever have to do type tem out once, and it is still more compact than above.
private void HandleException(Exception e) throws Excpetion
{
// Reject some types of exceptions
if (!((e is FileNotFoundException) ||
(e is ArgumentNullException) ||
(e is HttpException ) ||
(e is IncorrectInheritanceException )))
{
throw;
}
//Rest of code
...
}
Edit:
I see Konamiman has an improved version of this third option. I say go for that.
I would do it like this
public void LoadControl(ControlDestination controlDestination, string filename, object parameter)
{
try
{
// Get filename with extension
string file = GetControlFileName(filename);
// Check file exists
if (!File.Exists(file))
throw new FileNotFoundException();
// Load control from file
Control control = LoadControl(filename);
// Check control extends BaseForm
if (control is BaseForm)
{
// Set current application on user control
((BaseForm)control).CurrentApplication = this;
((BaseForm)control).Parameter = parameter;
// Set web user control id
control.ID = filename;
Panel currentPanel = null;
switch (controlDestination)
{
case ControlDestination.Base:
// Set current panel to Base Content
currentPanel = pnlBaseContent;
// Set control in viewstate
this.BaseControl = filename;
break;
case ControlDestination.Menu:
// Set current panel to Menu Content
currentPanel = pnlMenuContent;
// Set control in ViewState
this.MenuBaseControl = filename;
break;
}
currentPanel.Controls.Clear();
currentPanel.Controls.Add(control);
UpdateMenuBasePanel();
UpdateBasePanel();
}
else
{
throw new IncorrectInheritanceException();
}
}
catch (Exception e)
{
HandleException(e);
}
}
public void HandleException(Exception e)
{
if (e is FileNotFoundException
|| e is ArgumentNullException
|| e is HttpException
|| e is IncorrectInheritanceException)
{
// Load error control which shows big red cross
LoadControl(ControlDestination.Menu, "~/Controls/Error.ascx", null);
// Store error in database
DHS.Core.DhsLogDatabase.WriteError(exception.ToString());
// Show error in errorbox on master
Master.ShowAjaxError(this, new CommandEventArgs("ajaxError", exception.ToString()));
}
}

Categories

Resources