Programmatically suppressing exceptions in C# - c#

I have the following try-catch statement and I do not want to not throw the exception if the message property contains 'My error' in the text.
How can I programmatcially accomplish this? Also, would this be considered code-smell?
try
{
}
catch(Exception e)
{
if(e.Messages.Contains("My error"))
{
//want to display a friendly message and suppress the exception
}
else
{
throw e;
}
}

You shouldn't catch errors based on the error test. You should make your own exception class that extends exception:
class MyErrorException : Exception { }
and throw and catch those. (Excuse my syntax if it's wrong, I haven't done C# in a while).
That being said, throwing and catching your own Exceptions instead of propagating them is perfectly normal, and it is how you actually should do exception handling.

You should be catching the specific exception you're looking for. Quite frankly, that code is shocking. You should have something like ...
public class MyCoolException : Exception {
public MyCoolException(string msg) : base(msg) {}
}
public void MyCoolMethod() {
// if bad things happen
throw new MyCoolException("You did something wrong!");
}
Then later in your code you can use it like ...
try {
MyCoolMethod();
} catch (MyCoolException e) {
// do some stuff
}

Your code creates maintainability issues because a simple text change can have strange side effects. You can have your own exception class which inherits from System.Exception. Then instead of having an if you could do the following:
try
{
}
catch(MyException myException) //or just catch(MyException)
{
//display a friendly message
}
also you don't want to do throw e because it doesn't preserver the Stack, just throw; will do.

When I throw Exception rather than a derived class I always mean a failed assertion. I don't like failing out the backend because we are still able to receive a request (just not that one again). If we're really toast it will just error out on the next request anyway.
When the back end needs to generate an error message I have a ErrorMessage class that inherits from Exception and takes ErrorMessage and ErrorMessageTitle as constructor arguments.

Related

How to check if a function throws an exception in c#?

How to check if a function throws an exception in c#?
public List<string> GetFileNames()
{
try
{
// do something
// return something
}
catch(Exception ex)
{
// do something
// log something
}
}
then i will call GetFileNames() somewhere in my code, but I want to check if it throws an exception,
like,
var list = GetFileNames(); // can be 0 count
if(GetFileNames() throws an error)
{
DoThisMethod()
}
else
{
DoThisOtherMethod();
}
You have a lot of options here:
This is generally done with a Try... pattern like TryParse.
bool TryGetFileNames(out List<string> fileNames)
You can also return null.
You can"t do this in c#.
The closest thing to what you are describing is the "checked exceptions" which are implemented in java. In such case the function will declare it is throwing some exception like so :
public void foo() throws IOException {
// your code
}
At compile time you will be forsed to take care of this by either enclosing this in TryCatch block or propagate this the same way in your function.
In c# enclose the function in TryCatch block and use different function in case of faliure.
The fundamental problem is that you're attempting to handle an exception when you're not able to do so.
If GetFilenames cannot recover from the exception, it should throw an exception itself. That may be by omitting a try/catch entirely, or by catching it, wrapping and re-throwing.
public List<string> GetFilenames() {
try {
...
} catch (Exception e) {
throw new FileLoadException("Failed to get filenames", e);
// Or if you don't want to create custom exceptions, perhaps use an InvalidOperationException
}
}
Failing that, if you don't actually need to abstract the functionality, don't catch the exception in GetFilenames at all, then call it like this:
try {
var list = GetFilenames()
DoSomething();
} catch (Exception e) {
DoSomethingElse();
}
I think you can make it simpler:
public void ICallGetFileNames()
{
var list = new List<YourObject>();
try
{
list = GetFileNames();
DoThisOtherMethod();
}
catch (Exception ex)
{
DoThisMethod();
}
}
This way, if the exception is thrown by your GetFileNames method, the DoThisOtherMethod() won't be called, since your code is going directly to the Exception block. Otherwise, if no exception is thrown, your code will call the DoThisOtherMethod just after the GetFileNames method.

C# Cannot catch exceptions from another project within same solution

Got a strange problem: in a complex camera control program I'm working on, I use an SDK with a C# wrapper that was programmed by someone else. I include the wrapper as a separate project within the same solution. My own code is a WPF project that uses numerous calls into the SDK.
Everything synchronous works fine. However, depending on camera responses, the SDK occasionally sends asynchronous responses, usually in the form of throwing a custom exception with info about an error the camera reports. I implemented this using
try { ... } catch (ThisExceptionType) { ... }
However, NO exception ever gets caught. When an exception situation occurs, VisualStudio breaks, shows me the code where the SDK throws it and reports "ThisExceptionType was unhandled by user code", also showing the details of the exception condition (meaning it was apparently thrown properly). I verified that the exception corresponds with the error condition I created, so I'm sure I'm not looking at the wrong part of my code.
For testing purposes, I also replaced the line in the SDK where it throws ThisExceptionType with a standard exception, such as throw new ArgumentException("Test"); Same result: when changing my catch to catch (ArgumentException), I still cannot catch the condition and get a similar unhandled-by-user-code error.
Here's how the SDK throws the exception:
void CallEntryPoint( ...)
{
eNkMAIDResult result = _md3.EntryPoint(...);
switch (result)
{
// Note: Ignore these return values
case eNkMAIDResult.kNkMAIDResult_NoError:
case eNkMAIDResult.kNkMAIDResult_Pending:
break;
default:
throw new NikonException(...);
}
}
What am I missing here? Sorry if this is a simple issue - I'm pretty experienced in general programming but have not worked much with VisualStudio, and not a whole lot in C#, either.
UPDATE: According to the wrapper's author (this is actually Thomas Dideriksen's Nikon SDK wrapper), "when you're writing WPF or WinForms application, the C# wrapper relies on the inherent windows message queue to fire events on the UI thread."
He also states that the wrapper processes all camera tasks sequentially, so I guess my statement was incorrect about the wrapper throwing asynchronous exceptions - all code examples for the wrapper use the same try { ... } catch (ThisExceptionType) { ... } approach. For good measure, I tried some of your suggestions, for instance by hooking a handler to AppDomain.CurrentDomain.UnhandledException, but that approach failed to catch the exception, as well.
Any other ideas why this may be happening?
This article on MSDN may help. https://msdn.microsoft.com/en-us/library/dd997415(v=vs.110).aspx
There are differences in handling exceptions using Tasks in C#. Hopefully that will give a run down on different techniques you can use to handle the exceptions appropriately.
From the MSDN article:
Unhandled exceptions that are thrown by user code that is running
inside a task are propagated back to the calling thread, except in
certain scenarios that are described later in this topic. Exceptions
are propagated when you use one of the static or instance Task.Wait or
Task.Wait methods, and you handle them by enclosing the call
in a try/catch statement. If a task is the parent of attached child
tasks, or if you are waiting on multiple tasks, multiple exceptions
could be thrown.
And there are a couple solutions provided:
using System;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
var task1 = Task.Run( () => { throw new CustomException("This exception is expected!"); } );
try
{
task1.Wait();
}
catch (AggregateException ae)
{
foreach (var e in ae.InnerExceptions) {
// Handle the custom exception.
if (e is CustomException) {
Console.WriteLine(e.Message);
}
// Rethrow any other exception.
else {
throw;
}
}
}
}
}
public class CustomException : Exception
{
public CustomException(String message) : base(message)
{}
}
// The example displays the following output:
// This exception is expected!
Or you can do this:
using System;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
var task1 = Task.Run( () => { throw new CustomException("This exception is expected!"); } );
while(! task1.IsCompleted) {}
if (task1.Status == TaskStatus.Faulted) {
foreach (var e in task1.Exception.InnerExceptions) {
// Handle the custom exception.
if (e is CustomException) {
Console.WriteLine(e.Message);
}
// Rethrow any other exception.
else {
throw e;
}
}
}
}
}
public class CustomException : Exception
{
public CustomException(String message) : base(message)
{}
}
// The example displays the following output:
// This exception is expected!
I hope that helps!

How to catch the original (inner) exception in C#?

i'm calling a function that throws a custom exception:
GetLockOwnerInfo(...)
This function in turn is calling a function that throws an exception:
GetLockOwnerInfo(...)
ExecuteReader(...)
This function in turn is calling a function that throws an exception:
GetLockOwnerInfo(...)
ExecuteReader(...)
ExecuteReader(...)
And so on:
GetLockOwnerInfo(...)
ExecuteReader(...)
ExecuteReader(...)
ExecuteReaderClient(...)
Fill(...)
One of these functions throws an SqlException, although that code has no idea what an SqlException is.
Higher levels wrap that SqlException into another BusinessRuleException in order to include some special properties and additional details, while including the "original" exception as InnerException:
catch (DbException ex)
{
BusinessRuleExcpetion e = new BusinessRuleException(ex)
...
throw e;
}
Higher levels wrap that BusinessRuleException into another LockerException in order to include some special properties and additional details, while including the "original" exception as InnerException:
catch (BusinessRuleException ex)
{
LockerException e = new LockerException(ex)
...
throw e;
}
The problem now is that i want to catch the origianl SqlException, to check for a particular error code.
But there's no way to "catch the inner exception":
try
{
DoSomething();
}
catch (SqlException e)
{
if (e.Number = 247)
{
return "Someone";
}
else
throw;
}
i thought about catching SqlException right when it's thrown, and copy various values to the re-thrown exception - but that code is not dependant on Sql. It is experiencing an SqlException, but it has no dependency on SqlException.
i thought about catching all exceptions:
try
{
DoSomething(...);
}
catch (Exception e)
{
SqlException ex = HuntAroundForAnSqlException(e);
if (ex != null)
{
if (e.Number = 247)
{
return "Someone";
}
else
throw;
}
else
throw;
}
But that's horrible code.
Given that .NET does not let you alter the Message of an Exception to include additional information, what is the intended mechanism to catch original exceptions?
You need c# 6 / visual studio 2015 in order to do this using a predicate:
catch (ArgumentException e) when (e.ParamName == “…”)
{
}
Official C# Try/Catch Documentation
I hate to have to tell you this, but you cannot catch an inner exception.
What you can do is inspect one.
I suggest you catch your high-level exception (I believe it was LockerException) and inspect the InnerException property of that exception. Check the type, and if it's not a SqlException, check the InnerException of that exception. Walk each one until you find a SqlException type, then get the data you need.
That said, I agree with dasblinkenlight that you should consider -- if possible -- a heavy refactor of your exception framework.
Checking the error code of a wrapped exception is not a good practice, because it hurts encapsulation rather severely. Imagine at some point rewriting the logic to read from a non-SQL source, say, a web service. It would throw something other than SQLException under the same condition, and your outer code would have no way to detect it.
You should add code to the block catching SQLException to check for e.Number = 247 right then and there, and throw BusinessRuleException with some property that differentiates it from BusinessRuleException thrown in response to non-SQLException and SQLException with e.Number != 247 in some meaningful way. For example, if the magic number 247 means you've encountered a duplicate (a pure speculation on my part at this point), you could do something like this:
catch (SQLException e) {
var toThrow = new BusinessRuleException(e);
if (e.Number == 247) {
toThrow.DuplicateDetected = true;
}
throw toThrow;
}
When you catch BusinessRuleException later, you can check its DuplicateDetected property, and act accordingly.
EDIT 1 (in response to the comment that the DB-reading code cannot check for SQLException)
You can also change your BusinessRuleException to check for SQLException in its constructor, like this:
public BusinessRuleException(Exception inner)
: base(inner) {
SetDuplicateDetectedFlag(inner);
}
public BusinessRuleException(string message, Exception inner)
: base(message, inner) {
SetDuplicateDetectedFlag(inner);
}
private void SetDuplicateDetectedFlag(Exception inner) {
var innerSql = inner as SqlException;
DuplicateDetected = innerSql != null && innerSql.Number == 247;
}
This is less desirable, because it breaks encapsulation, but at least it does it in a single place. If you need to examine other types of exceptions (e.g. because you've added a web service source), you could add it to the SetDuplicateDetectedFlag method, and everything would work again.
Having an outer application layer care about the details of a wrapped exception is a code smell; the deeper the wrapping, the bigger the smell. The class which you now have wrapping the SqlException into a dbException is presumably designed to expose an SqlClient as a generic database interface. As such, that class should include a means of distinguishing different exceptional conditions. It may, for example, define a dbTimeoutWaitingForLockException and decide to throw it when it catches an SqlException and determines based upon its error code that there was a lock timeout. In vb.net, it might be cleaner to have a dbException type which exposes an ErrorCause enumeration, so one could then say Catch Ex as dbException When ex.Cause = dbErrorCauses.LockTimeout, but unfortunately exception filters are not usable in C#.
If one has a situation where the inner-class wrapper won't know enough about what it's doing to know how it should map exceptions, it may be helpful to have the inner-class method accept an exception-wrapping delegate which would take an exception the inner class has caught or would "like" to throw, and wrap it in a way appropriate to the outer class. Such an approach would likely be overkill in cases where the inner class is called directly from the outer class, but can be useful if there are intermediate classes involved.
Good question and good answers!
I just want to supplement the answers already given with some further thoughts:
On one hand I agree with dasblinkenlight and the other users. If you catch one exception to rethrow an exception of a different type with the original exception set as the inner exception then you should do this for no other reason than to maintain the method's contract. (Accessing the SQL server is an implementation detail that the caller is not/must not/cannot be aware of, so it cannot anticipate that a SqlException (or DbException for that matter) will be thrown.)
Applying this technique however has some implications that one should be aware of:
You are concealing the root cause of the error. In your example you are reporting to the caller that a business rule was invalid(?), violated(?) etc., when in fact there was a problem accessing the DB (which would be immediately clear if the DbException were allowed to bubble up the call stack further).
You are concealing the location where the error originally occurred. The StackTrace property of the caught exception will point to a catch-block far away from the location the error originally occurred. This can make debugging notoriously difficult unless you take
great care to log the stack traces of all the inner exceptions as well. (This is especially true once the software has been deployed into production and you have no means to attach a
debugger...)
Given that .NET does not let you alter the Message of an Exception to include additional information, what is the intended mechanism to catch original exceptions?
It is true that .NET does not allow you to alter the Message of an Exception. It provides another mechanism however to supply additional information to an Exception via the Exception.Data dictionary. So if all you want to do is add additional data to an exception, then there is no reason to wrap the original exception and throw a new one. Instead just do:
public void DoStuff(String filename)
{
try {
// Some file I/O here...
}
catch (IOException ex) {
// Add filename to the IOException
ex.Data.Add("Filename", filename);
// Send the exception along its way
throw;
}
}
As other peeps say, you cannot catch an the InnerException. A function such as this could help you get the InnerException out of the tree though:
public static bool TryFindInnerException<T>(Exception top, out T foundException) where T : Exception
{
if (top == null)
{
foundException = null;
return false;
}
Console.WriteLine(top.GetType());
if (typeof(T) == top.GetType())
{
foundException = (T)top;
return true;
}
return TryFindInnerException<T>(top.InnerException, out foundException);
}
I agree with the other comments that this is a code smell 🦨 and should be avoided. But if a refactor is not possible you could try something like this...
Create an extension method...
public static bool HasInnerException(this Exception ex, Func<Exception, bool> match)
{
if (ex.InnerException == null)
{
return false;
}
return match(ex.InnerException) || HasInnerException(ex.InnerException, match);
}
And use it like...
catch (Exception ex) when (ex.HasInnerException(e => e is MyExceptionThatIsHidden))
{
...
But really you should be solving for 👇
var exception = new Exception("wrapped exception 3",
new Exception("wrapped exception 2",
new Exception("wrapped exception 1",
new MyExceptionThatIsHidden("original exception")))); // <--- ???

a question about exception in c#

following is a code snippet:
class xxx
{
public xxx(){}
try
{
throw new Exception(InvalidoperationException);
}
catch(Exception x)
{
}
catch(InvalidoperationException x)
{
}
}
can anyone tell which exception will raise here and what is the reason behind it.
Wow, lots of problems here. Where to start?
That code won't compile. The try-catch block that you've defined is outside of any method, which is not allowed. You need to move it inside of a method.
Never throw a method that you intend to catch yourself later in the method. That's commonly known as using exceptions for "flow control", which is roundly discouraged. There is a performance cost associated with doing so, and it also makes it very confusing to monitor the exceptions that are being thrown when using a debugger when you have code that's throwing and catching it's own exceptions. Use boolean variables (known as flags) for flow control, if necessary.
Always catch the most derived exception class first. That means you should catch InvalidOperationException first, before trying to catch Exception. You need to reverse the order of your catch blocks in the code that you have.
You should practically never catch System.Exception. The only exceptions that you should catch are those that you explicitly understand and are going to be able to handle. There's virtually no way that you're going to know what went wrong or how to handle it when the only information you have is that a generic exception was thrown.
Along those same lines, you also should never throw this exception from your own code. Choose a more descriptive exception class that inherits from the base System.Exception class, or create your own by inheriting from the same.
I see that other answers are showing you sample code of what your code should look like, were it to be rewritten. I'm not going to do that because if I rewrote your code to be correct, I'd end up with this:
class Xxx
{
public Xxx()
{
}
}
Not particularly helpful.
If the code is like this
class xxx
{
public xxx(){
try
{
throw new Exception(InvalidoperationException);
}
catch(InvalidoperationException x)
{
}
catch(Exception x)
{
}
}
}
It should compile and raise your exception and catch. Otherwise your code will not compile at all.
No exception will be thrown as this code will not even compile.
Regardless - several points:
When using exception handling, put the more specific exception before the less specific ones (so the catch of InvalidOperationException should be before the one for Exception).
Catching Exception is normally no very useful.
If you catch an exception, do something with it.
You probably meant:
throw new InvalidOperationException();
However, the way you structured your exceptions, the catch(Exception x) block would have run.
You should write:
class xxx
{
public void Test()
{
try
{
throw new InvalidoperationException();
}
catch(InvalidoperationException exception)
{
// Do smth with exception;
}
catch(Exception exception)
{
throw; // Rethrows your exception;
}
}
}
InvalidOperationException inherits from Exception.
catch tries to processes the most specific branch, so catch (InvalidOperationException x) will be executed here.
Nope. It wouldn't compile. So, it there's no question about as to which exception will be generated.
Your code should be something like this :
class xxx
{
public void Test()
{
try
{
throw new InvalidoperationException();
}
catch(InvalidoperationException exception)
{
// Something about InvalidOperationException;
}
catch(Exception exception)
{
// Something about the Exception
}
}
}
Point to be noted :
Write more specific class of Exception first, hence we write InvalidOperationException prior to Exception class.
Ignoring the compile issue.... the first matching exception block (catch(Exception x)) will get the exception. You then ignore the exception and don't re-throw, so exception will be seen by the outside world. That doesn't make it good practice, though... in particular, catching an arbitrary Exception and ignoring it is risky - it could have been anything... it isn't necessarily the exception you thought it was.
Well, the code won't compile, but I'll just ignore that...
If I'll just look at the line:
throw new Exception(InvalidoperationException);
1st of all, according to MSDN there is no such constructor. So I will assume you meant the constructor: Exception(String msg, Exception innerException). Meaning:
throw new Exception("blabla", InvalidoperationException);
The exception that is being thrown is of type Exception and not InvalidOperationException. So ONLY catch(Exception x) can catch it.
If you would've thrown InvalidoperationException than the way you wrote the order of the catches, the Exception class would get caught first.
The order of the catches does matter.
The best advice I can give you is simply try it yourself and see what happens.

Throw exception with method by given parameter C#

I want to make a method, that throws a specific exception, by a parameter I give to the method. I have 3 userdefined exceptions, so instead of having to throw them every time I want to use them I want to make a method that handels it, so the parameter I give with my method is the exception I want to throw, but how do I do that?
I want to do something like this, but I am not really sure how to do it.
private void ExceptionMethod(custom exception)
{
try
{
//code that might fail
}
catch(exception ex)
{
throw new exception given by parameter(parameters from the exception);
}
}
FWIW I don't think this is a particulary good idea. Really, just throw your exception where it occurs, future maintainers of the code will thank you. (or at least not curse you)
If you have to do this thing, then its probably a better idea to pass an enumeration that you can switch on rather than the exception itself, then simply write a case statement to throw the exception you want.
Apart from the fact that this sounds like a bad idea, you can try the following:
private void TryElseThrow<TCustomException>(Action codeThatMightFail)
where TCustomException : Exception
{
try
{
codeThatMightFail();
}
catch (Exception e)
{
// Since there isn't a generic type constraint for a constructor
// that expects a specific parameter, we'll have to risk it :-)
throw
(TCustomException)Activator
.CreateInstance(typeof(TCustomException), e);
}
}
Use like so:
TryElseThrow<MyCustomException>(
() =>
{
throw new InvalidOperationException();
}
);
You were actually quite close:
private void ExceptionMethod(Exception customException)
{
try
{
//code that might fail
}
catch(Exception ex)
{
throw customException;
}
}
Will work, though I wouldn't recommend it for two reasons:
Catching Exception is a bad idea - you should just catch the exceptions that your code raises.
It's not a very good design (as others have pointed out).
So i dont see any problem in that.. as you say you already have your Custom Exception Written then you can do it like this.
in your parameter:
private void ExceptionMethod(CustomException myexception)
in catch:
throw myexception;
though its not a good Coding Design
Wouldn't it just be:
private void ExceptionMethod(MyCustomException exception)
{
try
{
//code that might fail
}
catch
{
throw exception;
}
}

Categories