How do I send an error to the constructor of the Exception class in addition to string? - c#

I am trying send exceptions to the base constructor but I don't know how to send it.
Should I need create an exception?
Here the code of the class:
public class InvalidEntityException : Exception
{
public InvalidEntityException(string message, Exception ex) : base(message, ex) { }
}
The exception look like this:
throw new InvalidEntityException( "Add function :: DAL", ???????);
How do I need throw the exceptions?

If you are inside a catch clause or have a current exception object available otherwise, use that exception object.
try
{
// code
}
catch(Exception ex)
{
throw new InvalidEntityException("Add function :: DAL", ex);
}
If you don't have a current exception object, just pass null.
throw new InvalidEntityException("Add function :: DAL", null);
From the documentation of the Exception class constructor:
public Exception (string? message, Exception? innerException);
innerException Exception
The exception that is the cause of the current exception, or a null
reference (Nothing in Visual Basic) if no inner exception is
specified.

Related

C# throw exception or ToString to ref string parameter

In case I write a dll for consumers, What is better in catch scope, throw an exception or write it to reference or out string parameter?
As far as I know exceptions ensure that failures do not go unnoticed because calling code didn't check a return code. https://learn.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions
Which is the best between the following 2 options?
OptionA
static void ThrowException(string value)
{
try
{
//Some code....
}
catch (Exception)
{
//Log Exception
throw;
}
}
Option B
static void RefException(string value, ref string errorMessage)
{
try
{
//Some code...
}
catch (Exception ex)
{
//Log Exception
errorMessage = ex.ToString();
}
}
I believe you are looking to create custom exceptions other than the .net exception
Update your code with the below code and create custom exceptions according to your need.
public void ThrowException()
{
if (string.IsNullOrEmpty(value))
{
throw new NullException();
}
if (value.Length > 10)
{
throw new LengthException();
}
}
public class NullException : Exception
{
NullException() : base(NullException.GetMessage())
{
}
public static string GetMessage()
{
return "value is null or empty";
}
}
public class LengthException : Exception
{
LengthException() : base(LengthException.GetMessage())
{
}
public static string GetMessage()
{
return "value length greater then 10 exception";
}
}
Option A
when you are validating some specific condition it will notify client with proper error message. Though other option are also doing same thing by throwing exception but it is not good practice to throw an exception for Validation. If any exception occur in application it is not good practice to throw exception with all details because it can lead to security threat by giving unnecessary details to client application. It is always recommended to log it in and show modified message to client application.
In this case you should go with throw Exception because you can pass custom message to client application and when you go with ref option there might be possibility that error message might get modified by another component of application which could mislead information of exception.

How to refactor try-catch with logging in abstract class?

I have code sample:
public abstract class BaseClass{
try
{
return Convert(value);
}
catch(Exception ex)
{
logger.LogError(ex);
throw new Exeption("Can't convert to type {0}", type);
}
}
How to refactor this one.
I can't remove throw because method must return type. But new exception will hide original one.
To solve your issue you should use the keyword "throw" alone.
try
{
return Convert(value);
}
catch(Exception ex)
{
logger.LogError(ex);
throw;
}
In that way the same exception as the one you received will be thrown again and you will keep all the stack trace.

ExpectedException Assert

I need to write a unit test for the next function and I saw I can use [ExpectedException]
this is the function to be tested.
public static T FailIfEnumIsNotDefined<T>(this T enumValue, string message = null)
where T:struct
{
var enumType = typeof (T);
if (!enumType.IsEnum)
{
throw new ArgumentOutOfRangeException(string.Format("Type {0} is not an Enum, therefore it cannot be checked if it is Defined not have defined.", enumType.FullName));
}
else if (!Enum.IsDefined(enumType, enumValue))
{
throw new ArgumentOutOfRangeException(string.Format("{1} Value {0} is not does not have defined value in Enum of type {0}. It should not be...", enumType.FullName, message ?? ""));
}
return enumValue;
}
and here would go the code to test the exceptions that are supposed to be threw
[TestMethod]
[ExpectedException(ArgumentOutOfRangeException(ArgumentException), "message")]
public void FailIfEnumIsNotDefined_Check_That_The_Value_Is_Not_Enum()
{
// PREPARE
// EXECUTE
// ASSERT
}
I don't have idea have to make the assert for the exceptions either.
ExpectedException just asserts that exception of specified type will be thrown by test method:
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void FailIfEnumIsNotDefined_Check_That_The_Value_Is_Not_Enum()
{
// PREPARE
// EXECUTE
// NO ASSERT!!
}
If you want to assert other parameters of exception, then you should use try..catch in your test method:
[TestMethod]
public void FailIfEnumIsNotDefined_Check_That_The_Value_Is_Not_Enum()
{
// PREPARE
try
{
// EXECUTE
Assert.Fail()
}
catch(Exception exception)
{
// ASSERT EXCEPTION DETAILS
}
}
You can write your own method for asserting exception was thrown to avoid repeating same test code over and over again:
public TException AssertCatch<TException>(Action action)
where TException : Exception
{
try
{
action();
}
catch (TException exception)
{
return exception;
}
throw new AssertFailedException("Expected exception of type " +
typeof(TException) + " was not thrown");
}
Usage:
var exception = AssertCatch<ArgumentOutOfRangeException>(() => /* EXECUTE */);
Assert.AreEqual("foo", exception.Message);
Assert the exception is throw with the correct exception message with :
var ex = Assert.Throws<Exception>(() => _foo.DoSomething(a, b, c));
Assert.That(ex.Message, Is.EqualTo("Your exception message"));
You must use ExpectedException differently:
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void MyTestSomething()
and then code your test so that the expected exception gets thrown.
While ExpectedException cannot be used as-is to verify the exception's message, you could implement your own exception validation logic by inheriting from ExpectedExceptionBaseAttribute:
By implementing your own expected exception verification. you can
specify additional information and requirements that the built-in
methods of the ExpectedExceptionAttribute class cannot handle, such as
the following:
Verifying the state of the exception.
Expecting more than one type of exception.
Displaying a custom message when a wrong type of exception is thrown.
Controlling the outcome of a negative test.
In your case, it could look something like this:
public sealed class ExpectedExceptionMessageAttribute<T> : ExpectedExceptionBaseAttribute
{
readonly string _expectedMessage;
public ExpectedExceptionMessageAttribute(string expectedMessage)
{
_expectedMessage = expectedMessage;
}
protected override void Verify(System.Exception exception)
{
// Handle assertion exceptions from assertion failures in the test method
base.RethrowIfAssertException(exception);
Assert.IsInstanceOfType(exception, typeof(T), "wrong exception type");
Assert.AreEqual(_expectedMessage, exception.Message, "wrong exception message");
}
}
HAving said that, I would still be inclined to use the direct try-catch approach though as it is more specific in where exactly the exception is expected to be thrown:
public static void Throws<T>(Action action, Predicate<T> predicate = null)
where T : Exception
{
try
{
action();
}
catch (T e)
{
if (predicate == null || predicate(e))
{
return;
}
Assert.Fail($"Exception of type {typeof(T)} thrown as expected, but the provided predicate rejected it: {e}");
}
catch (Exception e)
{
Assert.Fail($"Expected exception of type {typeof(T)} but a different exception was thrown: {e}");
}
Assert.Fail($"No exception thrown, expected {typeof(T)}");
}
You don't need an assertion if you're using ExpectedException attribute, in fact your code shouldn't be able to arrive at the assertion.
look:
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.expectedexceptionattribute.aspx
If you want to be sure the exception is thrown you should put an Assert.Fail() after the operation that should throw the exception, in this case if the exception is not thrown, the test will fail.

Problem with too many try catch

Is it possible to write a method like outType? TryDo(func, out exception, params) that call func(arg1,arg2,arg3,...) which params contains arg1,arg2,arg3,... and then it return func return value and if any exception occurred return null and set the exception?
Can this be done better by another function signature?
for example I have
string Foo1(int i) { return i.ToString()}
void Foo2(int[] a) {throw new Exception();}
and then call
string t = TryDo(Foo1, out ex, {i});
TryDo(Foo2, out ex, {});
-----------Edited------------------
string t;
SomeClass c;
try
{
t = Foo1(4, 2, new OtherClass());
}
catch (Exception ex)
{
Log(ex);
if (/*ex has some features*/)
throw ex;
}
try
{
Foo2();
}
catch (Exception ex)
{
Log(ex);
if (/*ex has some features*/)
throw ex;
}
.
.
.
I want to make it like this.
string t = TryDo(Foo1, out ex, {4, 2, new OtherClass());
Examine(ex);
SomeClass c = TryDo(Foo2, out ex, {});
Examine(ex);
What you are asking indicates that you have misunderstood how exceptions should be handled. Using try/catch everywhere can produce undesired results and make your application a whole lot harder to debug.
In short, only handle exceptions in the following cases:
You can handle the exception and return promised result
Catch layer specific exceptions and replace them with more generic exceptions (SqlException -> DataSourceException)
Catch all is OK in the top layer
Catch all is OK in threads (since uncaught exceptions in threads will crash your app)
More info in my blog: http://blog.gauffin.org/2010/11/do-not-catch-that-exception/
Update
PLEASE do not use throw ex. You are destroying the original call stack and therefore hiding where the exception was thrown originally. throw; is your puppy. Use it everywhere and all the time.
I would avoid using out parameters unless absolutely necessary.
Here is a quote from the Design Guidelines for Developing Framework Libraries:
Avoid using out or reference parameters.
Working with members that define out or reference parameters requires that the developer understand pointers, subtle differences between value types and reference types, and initialization differences between out and reference parameters.
You can instead create a return type that wraps the result of your call:
class CallResult<T> where T : class {
public CallResult(T result) { Result = result; }
public CallResult(Exception exception) { Exception = exception; }
public T Result { get; private set; }
public Exception Exception { get; private set; }
public Boolean IsSuccessful { get { return Exception == null; } }
}
Your method could then be implemented like this:
CallResult<T> TryDo<T>(Func<Object[], T> action, params Object[] args) where T : class {
try {
return new CallResult<T>(action(args));
}
catch (Exception ex) {
return new CallResult<T>(ex);
}
}
You can call it like this:
var callResult = TryDo<String>(Foo1, 4, 2, new OtherClass());
if (!callResult.IsSuccessful)
Examine(callResult.Exception);
However, if you intend to rethrow the exception in the Examine method loosing the stacktrace you should really reconsider your approach.
Yes, it's possible.
But why would you like to return a possible exception this way? You could throw further and process at the needed place.
Yes it is, but why would you want that?
int? TryDo(delegate d, out Exception e, params object[] par)
{
try
{
int res = d.Invoke(par);
e = null;
return res;
}
catch(Exception ex) { e = ex; return null; }
}
if you are having too many try...catch(I can't understand why) you could go for AOP to centralize the Exception handling.
Below you can find a link that explains how to use it:
http://www.codeproject.com/KB/architecture/ExceptionHandlingWithAOP.aspx

How to set the InnerException of custom Exception class from its constructor

How can I set the InnerException property of an Exception object, while I'm in the constructor of that object? This boils down to finding and setting the backing field of a property that has no setter.
BTW: I have seen this evain.net - Getting the field backing a property using Reflection but looking for non IL-based solution, if possible.
The constructor of Exception is the place where the Exception type is created, so I cannot call it using the base class constructor MyException() :base(...) etc.
You set the inner exception by calling the base ctor:
public MyException(string message, Exception innerException)
: base(message, innerException) {...}
If you need to run some code to get the exception, use a static method:
public MyException(SomeData data) : base(GetMessage(data), GetInner(data)) {...}
static Exception GetInner(SomeData data) {...} // <===== your type creation here!
static string GetMessage(SomeData data) {...}
The Exception class has an overloaded constructor accepting the inner exception as a parameter:
Exception exc = new Exception("message", new Exception("inner message"));
Is this what you are looking for?
Why can't you just call the constructor taking the InnerException as a parameter? If for some reason it's not possible, the backing field in System.Exception is:
private Exception _innerException;
I found it out using Redgate's Reflector. Using reflection I suppose you could set the inner exception.
Edit: In most cases it's not a good idea to access private fields via reflection, but I don't know enough about NT's case to know for sure if it's a good or bad idea.
Exception exceptionWithMoreInfo = new Exception("extra info", ex);
would be normal practice assuming you've trapped an exception to which you'd like to add more information before bubbling up.
If I understand your question you want to do something like this:
Exception ex = new Exception("test");
Exception innerEx = new Exception("inner");
ex.GetType().GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(ex, innerEx);
If you are in the constructor of an object that inherits from Exception you would use this instead of the first ex.
But this may not be the best way to handle whatever it is you are trying to handle.
Isn't InnerException supposed to be set when using the Exception(string, Exception) constructor? I think it's by design that you can't change this otherwise but you can always defer to the appropriate constructor at construction time:
class MyException : Exception {
public MyException()
: base("foo", new Exception("bar"))
{
...
}
...
}
I think you shouldn't ever break the exception chain in your code since that usually leads to errors you will never find again.
I know I'm really late to the party, but I find that this works.
public class MyException: Exception
{
public void SetInnerException(Exception exception)
{
typeof(Exception)
.GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(this, exception);
}
}
The trick is to get the actual Exception type's _innerException field, and then set the inner exception value to your class instance (MyException in this case).
This also works for variables.
Exception mainException = new Exception();
typeof(Exception)
.GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(mainException , new Exception("Something bad happened!"));
Use Redgate's Reflector to find the field. I doubt the Exception implementation will ever change... But it is a risk!
In my situation I used this code:
class Foo
{
void Bar(MyException myException = null)
{
try
{
SomeActions.Invoke();
}
catch (Exception ex)
{
if (myException != null)
{
// Here I regenerate my exception with a new InnerException
var regenMyException = (MyException)System.Activator.CreateInstance(myException.GetType(), myException.Message, ex);
throw regenMyException;
}
throw new FooBarException("Exception on Foo.Bar()", ex);
}
}
}
HTH someone ;).
Extension methods work well.
namespace MyNamespace
{
public static class ExceptionExtensions
{
public static void SetInnerException(this Exception exception, string innerExceptionMessage)
{
typeof(Exception)
.GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(exception, new Exception(innerExceptionMessage));
}
}
}
Then in your catch block when you want to add the inner exception:
try
{
throw new Exception("Main Message");
}
catch (Exception ex)
{
ex.SetInnerException("Inner Message");
throw;
}

Categories