I have something like this:
public byte[] AnyMethod(){
try {
...
}
catch (Exception e) {
string errorMessage =
"Some custom message, which should the caller of that method should receive";
// I thought something of this ,to pass through my custom exception to the caller?!
throw new ApplicationException(errorMessage);
//but this does not allow the method
}
}
But this:
throw new ApplicationException(errorMessage);
Will result in:
An exception of type 'System.ApplicationException' occurred in ...dll but was not handled in user code
How to do give the custom errror message to the caller of my above mentioned method ?
First, use a custom exception or at least one more meaningful instead of ApplicationException. Second, you have to catch the exception if your method throws it.
So the calling method should also wrap the method call in a try...catch:
try
{
byte[] result = AnyMethod();
}catch(MyCustomException ex)
{
// here you can access all properties of this exception, you could also add new properties
Console.WriteLine(ex.Message);
}
catch(Exception otherEx)
{
// all other exceptions, do something useful like logging here
throw; // better than throw otherEx since it keeps the original stacktrace
}
Here's an abstract, simplified example:
public class MyCustomException : Exception
{
public MyCustomException(string msg) : base(msg)
{
}
}
public byte[] AnyMethod()
{
try
{
return GetBytes(); // exception possible
}
catch (Exception e)
{
string errorMessage = "Some custom message, which should the caller of that method should receive";
throw new MyCustomException(errorMessage);
}
}
But note that you should not use exceptions for normal program flow. Instead you could either return true or false to indicate if the action was successful or use an out parameter for the byte[] like int.TryParse(or the other TryParse methods).
publy byte[] AnyMethod(){
try{
}catch(Exception e){
string errorMessage = string.Format("Some custom message, which should the caller of that method should receive. {0}", e);
//I thought something of this ,to pass through my custom exception to the caller?!
throw new ApplicationException(errorMessage);
//but this does not allow the method
}
}
OR
public byte[] AnyMethod(){
try{
}catch(Exception e){
string errorMessage = "Some custom message, which should the caller of that method should receive";
//I thought something of this ,to pass through my custom exception to the caller?!
throw new ApplicationException(errorMessage, e);
//but this does not allow the method
}
}
Related
I'm writing a service which's methods must not throw exceptions but should return a generic Message-object which contains the actual result of the method call and exceptions if any have occured. This Message class looks like this:
public class Message<T>
{
private List<Exception> exceptions = new List<Exception>();
public T Result { get; set; }
public void AddException(Exception x)
{
this.exceptions.Add(x);
}
public bool HasExceptions
{
get
{
return this.exceptions.Count > 0;
}
}
public IEnumerable<Exception> Exceptions
{
get
{
foreach (var exception in this.exceptions)
yield return exception;
}
}
}
Usually the implementation of a service method then looks like this:
public Message<int> MyServiceMethod()
{
var msg = new Message<int>();
try
{
// do something useful here
msg.Result = 42;
}
catch (Exception x)
{
msg.AddException(x);
}
return msg;
}
The caller can then handle exceptions if necessary.
var msg = service.MyServiceMethod();
if (msg.HasExceptions)
{
// Handle exceptions here
}
Now I have a service method with an argument which must be in a certain range. Since it feels natural for me to respond with an ArgumentOutOfRangeException if the argument is out of range, I implemented it like this:
public Message<int> MyOtherServiceMethod(int arg)
{
var msg = new Message<int>();
if (arg < 1)
{
msg.AddException(new ArgumentOutOfRangeException("arg", "Argument must be greater than 0"));
return msg;
}
// ...
return msg;
}
Basically this works. The only thing I'm missing is the stack trace of the exception. This is not a problem since I don't need that in my scenario. But it made me wonder, are there any other "side effects" which might cause trouble when the exception is used but not thrown?
You should use some construction that takes message and exception as arguments:
try
{
// do something useful here
}
catch (Exception x)
{
throw YourPreferredException(some_message, x);
}
This will make x available as yourPreferredException.InnerException property.
Also, I don't think it's a good design choice to have a method returning Message and running the try/catch block inside it (should be the other way around).
I would say that's not really the intended use of exceptions in C#. If you want a custom message then you just use the Exception constructor that takes a message and another instance of type Exception, this will give you a new exception with your custom message plus the original exception set as the instances InnerException property. You're just reinventing the wheel here with some custom 'message' class. If all you want to do is return a message (like you don't want to throw) then you should be taking the exceptions Message property and assigning it to some string or returning that string directly.
Here are a couple more idiomatic examples for handling your error;
Message ret = new Message();
try
{}
catch (Exception e)
{
ret.ErrorPropertyOfTypeString = e.Message;
}
return ret;
Message ret = new Message();
try
{}
catch (Exception e)
{
throw new Exception("My custom message here", e);
}
return ret;
Whatever you're doing, one of the two patterns above should probably used instead.
I have a class which contains several methods.
One of the methods runs in a while loop (MainMethod).
I call out to helper methods in the same class from MainMethod.
The Try Catch is contained within MainMethod where most of the execution occurs.
If an exception occurs in a helper method which doesn't contain a Try Catch, will it be caught further up? i.e. inside MainMethod which called the helper method.
class Class1
{
public MainMethod()
{
while (true)
{
try
{
// ...
// ...
// ...
HelperMethod();
// ...
// ...
}
catch (Exception e)
{
// Console.WriteLine(e.ToString());
// logger.log(e.ToString();
// throw e;
// ...
}
}
}
public HelperMethod()
{
// No Try Catch
// if (today == "tuesday") program explodes.
}
}
Thanks.
Yes. If a method has no try/catch block it will "bubble up" the stack and be caught by the next handler up the chain. If there is no handler, that's when your program terminates because an exception was "unhandled".
Yes it will. Something like this:
public class Helper
{
public void SomeMethod()
{
throw new InvalidCastException("I don't like this cast.");
}
public void SomeOtherMethod()
{
throw new ArgumentException("Your argument is invalid.");
}
}
public class Caller
{
public void CallHelper()
{
try
{
new Helper().SomeMethod();
}
catch (ArgumentException exception)
{
// Do something there
}
catch (Exception exception)
{
// Do something here
}
try
{
new Helper().SomeOtherMethod();
}
catch (ArgumentException exception)
{
// Do something there
}
catch (Exception exception)
{
// Do something here
}
}
}
Note that if caller application handles that specific type of exception, specific catch block will be called.
IMHO, it is good to handle specific exceptions that may be thrown by methods you call from your code. However, that also means that author of method you are calling created a decent document sharing exceptions that we need to expect from his code.
try
{
}
catch (Exception objEx)
{
clsLog.blnLogError(this.GetType().Name, MethodBase.GetCurrentMethod().Name, String.Format("Error In {0}...", MethodBase.GetCurrentMethod().Name), objEx.Message);
}
This is my Code and I need something like.
catch (MyException objEx)
{
}
class MyException
{
method()
{
//method overload with necessary parameters.
clsLog.blnLogError(this.GetType().Name, MethodBase.GetCurrentMethod().Name, String.Format("Error In {0}...", MethodBase.GetCurrentMethod().Name), objEx.Message);
}
}
In that exception class I need to get the curent class name and method name instead of writing every time.
How to achieve this?
UPDATE
[Serializable]
public class MyException : Exception
{
public MyException(string message, Exception innerException, object obj)
: base(message, innerException)
{
}
}
try
{
int f = int.Parse("d");
}
catch (MyException objEx)
{
}
It is not catching the exception and I need the method name, class name of the one where it throws error.
This cannot be done by inheriting, you will need to write an extension method so that you can call your logging method on all exception types, no matter whether they were declared by yourself or not.
To create an extension method create a static class containing a static method doing your work. Prepend the first argument of the method with the keyword this, indicating to the compiler that this method can be invoked like a member method on objects of the type of the first parameter (in your case Exception):
public static class ExceptionExtensions
{
public static void Log(this Exception ex)
{
var stackTrace = new StackTrace();
var callingMethod = stackTrace.GetFrame(1).GetMethod();
var methodName = callingMethod.Name;
var className = callingMethod.DeclaringType.Name;
clsLog.blnLogError(className, methodName, string.Format("Error In {0}...", methodName), ex.Message);
}
}
then you can call that method on every exception:
try
{
int f = int.Parse("d");
}
catch(Exception ex)
{
ex.Log();
}
For more information on extension methods see the C# Programming Guide.
I've written a custom exception AbortTestException, which is pretty simple:
class AbortTestException : Exception
{
public AbortTestException(string message)
: base(message) { }
}
Then I have a function that will throw it:
class Foo
{
public void Throws()
{
throw new AbortTestException("hi");
}
}
And Throws() gets called via method reference:
class Program
{
static void Main(string[] args)
{
Type myType = (typeof(Foo));
var method = myType.GetMethod("Throws");
try
{
method.Invoke(new Foo(), null);
}
catch (AbortTestException ex)
{
Console.WriteLine("AbortTestException");
}
catch (Exception ex)
{
Console.WriteLine("Exception");
}
}
}
However, something weird happens. Even though Throws rises an AbortTestException, the catch(Exception) block gets used (instead of the catch(AbortTestException) block). I tried putting the "throw new AbortTestException("hi")" portion in the try block itself, and verified that the correct catch block is used.
Is there some reason an exception would be re-cast when emitted via MethodInfo.invoke()?
http://msdn.microsoft.com/en-us/library/4k9x6bc0.aspx
Per the MSDN a TargetInvocationException is thrown if the invoked method or constructor throws an exception.
Did you check the nested Exception? My guess the original exception (AbortTest...) is wrapped in a nested one. The nested Exception will be in the InnerException property of the one which is caught by your code
Remember that catching Exception will match any exception that isn't caught by a more specific catch block before it:
Type myType = (typeof(Foo));
var method = myType.GetMethod("Throws");
try
{
try
{
method.Invoke(new Foo(), null);
}
catch (AbortTestException ex)
{
Console.WriteLine("AbortTestException");
}
catch(TargetInvocationException tie)
{
throw tie.InnerException;
}
catch (Exception ex)
{
Console.WriteLine("Exception");
}
}
catch(AbortTestException ate)
{
Console.WriteLine("AbortTestException after re-throw from TargetInvocationException");
}
This question has been asked in different ways before, but the answers don't help me, because (1) I don't have control over the built-in Exception classes, and (2) Activator.CreateInstance() returns an object/instance, where I need a true dynamic type.
I'm trying to create an extension method that allows me to throw a FaultException out of my WCF service, based off the exception I catch. For example:
try {
...
}
catch (ArgumentNullException exc) {
throw new FaultException<ArgumentNullException>(exc);
}
is straight-forward. But if I want to extend this in a general way, I'd use an extension class, like:
try {
...
}
catch (Exception exc) {
exc.ThrowFaultException();
}
Where I get hung up, of course, is the implementation of the extension method:
public static void ThrowFaultException(this Exception exc) {
// Gives me the correct type...
Type exceptionType = exc.GetType();
// But how the heck do I use it?
throw new FaultException<???>(exc);
}
The answers here and here don't help. Any ideas?
Try this:
public static void ThrowFaultException<TException>(this TException ex) where TException : System.Exception
{
throw new FaultException<TException>(ex);
}
public static void ThrowFaultException(this Exception exc)
{
// Gives me the correct type...
Type exceptionType = exc.GetType();
var genericType = typeof(FaultException<>).MakeGenericType(exceptionType);
// But how the heck do I use it?
throw (Exception)Activator.CreateInstance(genericType, exc);
}
You don't need to cast the object returned by Activator.CreateInstance to FaultException<?> to throw it. Casting it to Exception is enough:
var type = typeof(FaultException<>).MakeGenericType(exc.GetType());
throw (Exception)Activator.CreateInstance(type, exc);
I wouldn't throw the exception in ThrowFaultException though:
try
{
...
}
catch (Exception e)
{
throw e.WrapInFaultException();
}
public static Exception WrapInFaultException(this Exception e)
{
var type = typeof(FaultException<>).MakeGenericType(e.GetType());
return (Exception)Activator.CreateInstance(type, e);
}