Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
i know this question has been asked similarly quite often, but I can't seeem to find an answer that I'm satisfied with. I want do learn this "right" from the start.
string [] list = {"foo", "bar", "foo"};
for(int i = 0; i<list.Length;i++)
{
try
{
//begin sql transaction
if(!list[i].Equals("foo"))
throw new Exception("foo exception");
else
{
//save stuff into DB
Console.WriteLine(list[i]);
//commit transaction here
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
//rollback transaction here
}
Console.WriteLine("Next record");
}
I've tested the code in the following fiddle https://dotnetfiddle.net/0nftFD and now my questions:
If i were to handle files in a for loop analog to the above example and if one of them had an IO exception for example, i would log it, email to admin, etc. and then continue with the next file.
As far as i can see it would work like this, would this be good/bad practise? I'd like to learn this properly right away :)
EDIT: Because i failed to mention this before, I would also get specific exceptions.
Ressources i failed to see before:
similar question: https://forums.asp.net/t/1943641.aspx?How+do+I+continue+after+an+exception+is+caught+
.net site: https://learn.microsoft.com/de-de/dotnet/csharp/programming-guide/exceptions/using-exceptions
Depending on the requirements you might be able to separate the data processing and error handling:
Iterate through the files
In case of exception capture into enough information into a List, Dictionary to be able process later
After looping through all the object loop through the errors
For example:
string[] list = {"foo", "bar", "foo"};
var errors = new Dictionary<string, ExceptionDispatchInfo>();
for(int i = 0; i < list.Length; i++)
{
try
{
if(!list[i].Equals("foo"))
throw new Exception("foo exception");
else
Console.WriteLine(list[i]);
}
catch(Exception ex)
{
var edi = ExceptionDispatchInfo.Capture(ex);
errors.Add($"{list[i]}_{i}", edi);
}
Console.WriteLine("Next record");
}
foreach(var error in errors)
{
//Process error and throw the original exception if needed
//error.Value.Throw();
}
Your example is how to handle it, though you may wish to catch only specific exceptions and not all. In some cases you may want to exit the processing due to speicific exceptions - for instance - if your database is not reachable then no need to keep going through all the files only to find it fails on each iteration.
In that example you could nest the loop in a try catch also such that it may catch exception types that are thrown which you specifically wish to be terminal to the loop processing. An example of it being nested is shown below.
try
{
for(int i=0; i < 100; i++)
{
try
{
//do something
}
catch(IOException ex)
{
}
}
}
catch(SecurityException sex)
{
}
Incidentally - you might also consider that you can batch the database (depending how many files you might be processing) and make your changes in one go. That's a performance trade-off you might wish to consider.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am trying to update some documents in DocumentDb / CosmosDb, and if that fails, need to do something else, and then if that fails to log it out...
try {
do a thing w/ database
}
catch (DocumentClientException dce1) {
try {
do another, alternative thing w/ database
}
catch (DocumentClientException dce2) {
log to app insights.
}
}
I'm not sure about this, it seems clunky.. what do you guys think?
For additional bonus points, I need to do this quite frequently.. so something that I can farm off somewhere would be even better ;)
Personally I'd avoid intermixing exception flow with a functional logic flow. It can get brittle. Instead, convert the exception into a logical flag and use it in ordinary logic constructs.
So step 1 is catch the exception and set a variable or return value based on it, and wrap this in an independent method to mask the messiness from everyone else:
bool TryDoSomethingWithDataBase()
{
try
{
//Do thing that could fail
return true;
}
catch(SpecificException ex)
{
return false;
}
}
bool TryDoSomethingElseWithDataBase()
{
try
{
//Do thing that could fail
return true;
}
catch(SpecificException ex)
{
return false;
}
}
Step 2 is to write the logic as usual:
if (!TryDoSomethingWithDatabase())
{
if (!TryDoSomethingElseWithDatabase())
{
LogFatalError();
}
}
Or
var ok = TryDoSomethingWithDatabase();
if (ok) return;
ok = TryDoSomethingElseWithDatabase();
if (ok) return;
LogFatalError();
Why would your thing with the Database fail? You would be better coding for the conditionals you are aware of and expecting and do different things if you want to go into a different logic for processing the result.
Try catch will catch anything and everything, so if your connection to the db fails etc or if you are trying to read or insert malformed data etc.
Try catch does have various exceptions that you can investigate further and catch the specific exception you are interested in.. e.g.
try
//try something
catch (Exception ex)
{
if (ex is FormatException || ex is OverflowException)
{
//Do something specific;
return;
}
throw;
}
This is ok but if you say you'll have this over and over it's better to extract that logic and reuse it.
One way of doing this is to have a method that accept the first and section actions as parameters, for example:
public void TryThis(Action doFirst, Action doSecond)
{
try {
doFirst();
}
catch (DocumentClientException dce1) {
try {
doSecond();
}
catch (DocumentClientException dce2) {
log to app insights.
}
}
}
And then use it like so:
public void DoSomethig1()
{
...
}
public void DoSomething2()
{
...
}
TryThis(DoSomething1, DoSomething2)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Is it reasonable to think I can write a void function to take in an Exception and output the stuff that a catch block normally would? Here's an example of my exception catcher (which I would make individual ones for common exceptions I handle):
private void exCatch(Exception ex)
{
MessageBox.Show("ERROR - " + blah blah blah + ex.ToString(), blah blah);
}
Here it is in practice:
try
{
stuff
}
catch (Exception e)
{
exCatch(e);
}
Is this an efficient way to handle exceptions? If this is reasonable, do people do this? It seems like it could speed up your coding not having to copy paste all your exception junk over and over. Thanks for any help!
There is no problem with that at all. In fact, adding functions to reduce code repetition is definitely advisable. Then if you want to change say the MessageBox buttons you change it once and you're done everywhere.
One note is that you should consider only catching certain types of exceptions that you're expecting. If you're catching an exception it should be because you know where it came from and exactly what to do with it. Or else you might be catching something that should be handled at a higher level and your app can get into an invalid state. Here's an example.
ArgumentNullException
FormatException
OverflowException
Are the exceptions that Int32.Parse(string) throws. Lets say you know you wont be passing in Null this is how MSDN shows you should handle the function:
using System;
public class Example
{
public static void Main()
{
string[] values = { "+13230", "-0", "1,390,146", "$190,235,421,127",
"0xFA1B", "163042", "-10", "007", "2147483647",
"2147483648", "16e07", "134985.0", "-12034",
"-2147483648", "-2147483649" };
foreach (string value in values)
{
try {
int number = Int32.Parse(value);
Console.WriteLine("{0} --> {1}", value, number);
}
catch (FormatException) {
Console.WriteLine("{0}: Bad Format", value);
}
catch (OverflowException) {
Console.WriteLine("{0}: Overflow", value);
}
}
}
}
https://msdn.microsoft.com/en-us/library/b3h1hf19(v=vs.110).aspx
Always look up the exceptions that a method can throw and always document those that you are catching and throwing in your methods.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Is it a good idea to wrap the return value of the functions in a class. It provides ease of coding and you can avoid try...catch
I'm taking about doing something like this.
public class ResultWrapper
{
public bool Success{get;set;}
public Exception ErrorMessage{get;set;}
public object Result{get;set;} //not object essentially(any type)
public Result()
{
Success=false;
ErrorMessage="";
Result=null;
}
}
public ResultWrapper DoSomething(parameters....)
{
var result=new ResultWrapper()
try
{
}
catch(Exception ex)
{
result.Error=ex;
}
return result;
}
and then calling it like
static void main()
{
var result=DoSomething(parameters...);
if(result.Success)
{
//Carry on with result.Result;
}
else
{
//Log the exception or whatever... result.Error
}
}
EDIT:
consider this
static void main()
{
var result=Login(); //throws an exception
if(result.Success)
{
//retrive the result
//carry on
result=PostSomeStuff(parameter);
if(result.Success)
{
}
else
{
Console.WriteLine("Unable to Post the data.\r\nError: {0}",result.Error.Message);
}
}
else
{
Console.WriteLine("Unable to login.\r\nError: {0}",result.Error.Message);
}
}
isn't it simpler then to wrapping a try..catch outside of each function???
static void main()
{
try
{
var result=Login();
var result1=result=PostSomeStuff(parameter);
// a lot of functions doing seprate things.
}
catch(Exception ex)
{
//what to do...?
}
}
No, this is an anti-pattern. If there is any exception that you don't know how to handle then let it propagate up. Returning exception objects in the return value is a very bad idea when the language has support for exceptions.
If the method is successful it should return the value directly; if it fails it should throw an exception. (Caveat: Some methods might return bool indicating success or failure, and store the result in an out parameter. For example, int.TryParse(), Dictionary<TKey, TValue>.TryGetValue(), etc. Since exceptions can be expensive, some operations might be better suited to simply return a flag indicating failure if failure is expected to be frequent, but this should be a rare occurrence.)
Generally no. There may be specific cases where it's a good idea, but I wouldn't recommend it as a default.
It will make it impossible to allow the exception to "bubble up" until it gets to a good place to handle it. It will make the code harder to understand.
This is awful. Think how many if statement would be added to your code, just to check if an exception was thrown.
Also, think of it this way: if this were a great idea, then the .NET Framework itself would do this. Have you ever seen this pattern anywhere in .NET? I haven't.
You should almost always match the semantics of what the framework does that you are using, otherwise you end up with a weird mish-mash. Soon you have 10 competing coding "standards."
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Are nested Try/Catch blocks a bad idea?
Currently I am using try catch within try catch ? The current senario requires it in our application.
void MyFun()
{
try
{
//Process logic 1
// ......
try
{
//Process logic 2
// ......
} catch (Exception ex)
{
//write an error details in database
}
//Process Logic 3
// ......
} catch (Exception ex)
{
//show error msg
}
}
No particular problem with this especially if you want to handle the exceptions differently.
However, if the inner exception and the outer exception are of different types E1, E2 respectively and E1 is not a parent of E2, you can have two adjacent catch clauses.
try
{
// do something
}
catch (E1 e1)
{
}
catch (E2 e2)
{
}
As noted by Rob and J.Steen - this is slightly different than the case in the question as in this case is E1 is thrown the code after it will not be executed.
A nested try/catch is fine. what you want to stay away from is changing the logical flow of your code based on the try catch. In other words, you shouldn't treat a try/catch as an if/else block. so this isn't ideal:
//over the top example just to demonstrate my point
public bool IsNumberTen(int x)
{
try
{
if(x > 10)
throw new NumberTooHighException();
else if(x < 10)
throw new NumberTooLowException();
else
return true;
}
catch(NumberTooHighException)
{
return false;
}
catch(NumberTooLowException)
{
return false;
}
}
This item suggests that its not a bad thing and that you would only have to handle the error in another way any way.
Exception handling try catch inside catch
I don't see why not. If you have logic in the catch which may fail or raise an exception that requires handling then it makes sense.
Its a little difficult to answer this question without knowing what logic is in here.
Certainly in terms of performance, nested exception handling will incur a greater cost, but general rule of thumb is only catch exceptions that you as a developer understand how to handle. This overlaps into the practice of TDD where if you have a good enough set of tests you can identify where the expected exceptions should be, then this will dictate your exception logic.
I would say this: it's not bad. Whether it's good depends on your program, and whether such a concept makes sense given your method's logic and contracts.
Edit: I'd suggest checking out the article Exception Cost: When to throw and when not to. It outlines what is most expensive for exception management in the CLR.
I am trying to think of situations where you may want a nested block... perhaps if you are making database changes and you are using the try catch as a virtual transaction, you may want to try to update some properties but then carry on if that fails, but also catch an overall exception if and when you actually commit to the database update itself.
Even with this considered, you should never need to do this... It should be perfectly sufficient to simply stack blocks next to each other like so:
void MyFun()
{
try
{
//Process logic 1
// ......
} catch (Exception ex)
{
//show error msg
}
try
{
//Process logic 2
// ......
} catch (Exception ex)
{
//write an error details in database
}
}
It is also probably worth noting that if you find the need to nest try catch blocks then there is probably a better way you could be designing your code.
EDIT: Itay's answer is also somewhat better than nesting, although it will not allow you to carry on in the block once you have caught an exception.
Hope this helps!
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
What would a piece of code which "uses exceptions to control flow" look like? I've tried to find a direct C# example, but cannot. Why is it bad?
Thanks
By definition, an exception is an occurrence which happens outside the normal flow of your software. A quick example off the top of my head is using a FileNotFoundException to see if a file exists or not.
try
{
File.Open(#"c:\some nonexistent file.not here");
}
catch(FileNotFoundException)
{
// do whatever logic is needed to create the file.
...
}
// proceed with the rest of your program.
In this case, you haven't used the File.Exists() method which achieves the same result but without the overhead of the exception.
Aside from the bad usage, there is overhead associated with an exception, populating the properties, creating the stack trace, etc.
It's roughly equivalent to a goto, except worse in terms of the word Exception, and with more overhead. You're telling the code to jump to the catch block:
bool worked;
try
{
foreach (Item someItem in SomeItems)
{
if (someItem.SomeTestFailed()) throw new TestFailedException();
}
worked = true;
}
catch(TestFailedException testFailedEx)
{
worked = false;
}
if (worked) // ... logic continues
As you can see, it's running some (made-up) tests; if they fail, an exception is thrown, and worked will be set to false.
Much easier to just update the bool worked directly, of course!
Hope that helps!
Bad
The below code catches an exception that could easily be avoided altogether. This makes the code more difficult to follow and typically incurs a performance cost as well.
int input1 = GetInput1();
int input2 = GetInput2();
try
{
int result = input1 / input2;
Output("{0} / {1} = {2}", input1, input2, result);
}
catch (OverflowException)
{
Output("There was an overflow exception. Make sure input2 is not zero.");
}
Better
This code checks for a condition that would throw an exception, and corrects the situation before the error occurs. This way there is no exception at all. The code is more readable, and the performance is very likely to be better.
int input1 = GetInput1();
int input2 = GetInput2();
while (input2 == 0)
{
Output("input2 must not be zero. Enter a new value.");
input2 = GetInput2();
}
int result = input1 / input2;
Output("{0} / {1} = {2}", input1, input2, result);
Here's a common one:
public bool TryParseEnum<T>(string value, out T result)
{
result = default(T);
try
{
result = (T)Enum.Parse(typeof(T), value, true);
return true;
}
catch
{
return false;
}
}
Probably the grossest violation I've ever seen:
// I haz an array...
public int ArrayCount(object[] array)
{
int count = 0;
try
{
while (true)
{
var temp = array[count];
count++;
}
}
catch (IndexOutOfRangeException)
{
return count;
}
}
I'm currently working with a 3rd party program that does this. They have a "cursor" interface (basically an IEnumerable alternative), where the only way to tell the program you're finished is to raise an exception. The code basically looks like:
// Just showing the relevant section
bool finished = false;
public bool IsFinished()
{
return finished;
}
// Using something like:
// int index = 0;
// int count = 42;
public void NextRecord()
{
if (finished)
return;
if (index >= count)
throw new APIProgramSpecificException("End of cursor", WEIRD_CONSTANT);
else
++index;
}
// Other methods to retrieve the current value
Needless to say, I hate the API - but its a good example of exceptions for flow control (and an insane way of working).
I'm not fond of C# but you can see some similarities between try-catch-finally statements and normal control flow statements if-then-else.
Think about that whenever you throw an exception you force your control to be passed to the catch clause. So if you have
if (doSomething() == BAD)
{
//recover or whatever
}
You can easily think of it in terms of try-catch:
try
{
doSomething();
}
catch (Exception e)
{
//recover or do whatever
}
The powerful thing about exception is that you don't have to be in the same body to alter the flow of the program, you can throw an exception whenever you want with the guarantee that control flow will suddently diverge and reach the catch clause. This is powerful but dangerous at the same time since you could have done actions that need some backup at the end, that's why the finally statement exists.
In addition you can model also a while statement without effectively using the condition of it:
while (!finished)
{
//do whatever
}
can become
try
{
while (true)
{
doSomethingThatEventuallyWillThrowAnException();
}
}
catch (Exception e)
{
//loop finished
}
A module developed by a partner caused our application to take a very long time to load. On closer examination, the module was looking for a config file at app startup. This by itself was not too objectionable, but the way in which it was doing it was outrageously bad:
For every file in the app directory, it opened the file and tried to parse it as XML. If a file threw an exception (because it wasn't XML), it caught the exception, squelched it, and tried the next file!
When the partner tested this module, they only had 3 files in the app directory. The bonehead config file search didn't have a noticeable effect on the test app startup. When we added it to our application, there were 100's of files in the app directory, and the app froze for nearly a minute at startup.
To add salt to the wound, the name of the config file the module was searching for was predetermined and constant. There was no need for a file search of any kind.
Genius has its limits. Stupidity is unbounded.
One example would be using exceptions to return a result from a recursive method:
public void Search(Node node, object data)
{
if(node.Data.Equals(data))
{
throw new ResultException(node);
}
else
{
Search(node.LeftChild, data);
Search(node.RightChild, data);
}
}
Doing something like this is a problem for several reasons.
It's completely counter-intuitive. Exceptions are designed for exceptional cases. Something working as intended should (we hope) never be an exceptional scenario.
You can't always rely on an exception being thrown and propagated to you. For example, if the exception-throwing code runs in a separate thread, you'll need some extra code to capture it.
It is a potential performance problem. There is an overhead associated with exceptions and if you throw a lot of them, you might see a performance drop in your application.
There are a few more examples and some interesting discussion on this subject here.
Disclaimer: The code above is adapted from the first sample on that wiki page to turn it into C#.