Imagine, that u have a Method:
public void SometimesIFail(string text)
{
bool everythingOk = true;
try
{
//Anything
}
catch(Exception)
{
//Anything
everythingOk = false
}
}
Now I would like to do something like that:
foreach (String text in texts)
{
if(!SometimesIFail(text)) //If SometimesIFail() Failed (walked into Catch) Do the same for the next TEXT from the List: texts
{
SometimesIFail(text); // The Next Text - Until iterated through all the texts..
//FROM HERE ON, I HAVE A RECURSIVE CALL, THAT MEANS THAT THIS CODE, MUSTNT BE EXECUTED
//Any Code..
}
else
{
//Do Something
}
}
Whats the best way, to solve the problem?
EDIT:
After the test (Checking if it was ok), I want to do something, when it did not was OK:
foreach (String text in texts)
{
if(!SometimesIFail(text))
{
//HERE I will do SometimesIFail(text) for the next text (in foreach)
// And here is a Recursive Call which should be called, after the foreach iterated through all the texts..
}
}
Let the exception bubble up as far as possible. So remove the try/catch from the SometimesIFail method and catch the error closer to the user. Something like this:
try {
SometimesIFail();
// Do stuff
} catch {
// Tell the user an error has occurred.
}
And do consider exceptions for what they are called - they are exceptions and shouldn't be used for flow control. If there is a problem with your code that makes it crash sometimes, fix the problem instead.
I think without try catch if you solved your problem then it would be better option...
At first I thought I knew what you were looking for, then I read the comments in the code snippet, so now I'm not so sure. Here is my answer based on what I think you want. It looks like you want to check the SometimesIFail method for success and if it succeeds execute some code, if it fails you want to continue to the next iteration. Here's what I would do for that scenario:
// Don't use a void here, use a bool
public bool SometimesIFail(string text)
{
try
{
//Anything
return true;
}
catch(Exception)
{
//Anything
return false;
}
}
....
foreach (String text in texts)
{
if(SometimesIFail(text)) // Evaluates to true for success
{
// Do your success matching code
}
// There doesn't need to be an else condition if you're
// only passing to the next iteration
}
Try using this:
public bool SometimesIFail(string text)
{
try
{
//Anything
return false;
}
catch(Exception)
{
//Anything
return true;
}
}
foreach (String text in texts)
{
SometimesIFail(text);
if(SometimesIFail(text))
{
// returned true - exception was thrown
SometimesIFail(text);
}
else
{
//Do Something
}
}
Related
Is there anything wrong with doing something like this? I am basically just trying to assert that these elements exist and if not then return false:
public static bool IsAllDataPresent()
{
try
{
Driver.Instance.FindElement(By.Id("id-a");
Driver.Instance.FindElement(By.Id("id-b");
Driver.Instance.FindElement(By.Id("id-c");
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
Is this is wrong then any help would be greatly appreciated. I am new to try catch.
If there is a method that tells you what you need to know without throwing, then call it.
If there is not, then you are in what I call a "vexing exception" situation. The best way out of that situation is to write the method that is missing.
public static bool IsPresent(string id)
{
try
{
Driver.Instance.FindElement(By.Id(id);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
And now your method is sensible:
public static bool IsAllDataPresent() =>
IsPresent("id-a") && IsPresent("id-b") && IsPresent("id-c");
Notice how when you write the correct abstraction, your method bodies get nice and concise.
For your specific question about checking multiple things and using try-catch... there's no problem with that, other than if it does fail, you're throwing away the exception which would tell you which of the things was missing.
In general, if you're expecting to find elements, you should wait for them to exist. If they exist right now, no waiting is done.
Example:
WebDriverWait wait = new WebDriverWait(Driver.Instance, new TimeSpan(0,0,5));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-a")));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-b")));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-c")));
return true;
If you don't wait, there's a risk you'll test the browser for an element which isn't there right now, but will exist in a few milliseconds time, and your script gives a premature, false negative, answer.
As you are trying to assert that these three elements exist and if not then return false you can optimize your code as per the code block below :
public static bool IsAllDataPresent()
{
if(Driver.Instance.FindElement(By.XPath("//*[#id='id-a' or #id='id-b' or #id='id-c']")).size() != 3)
{
Console.WriteLine("All the 3 elements exists")
return true;
}
else
{
Console.WriteLine("All the 3 elements doesn't exists")
return false;
}
}
I couldn't find a answer to this, probably because I'm not asking this question in a proper way.
So, I'm writting a method that is inside a class, and at some point I want it to test for the formatting of a string. If it is not correct, I want it to show a message to the user, and to stop the execution, so that the user can fix that mistake. I have this:
if (Is not properly formated)
{
//get error information
//show error box with the formation error line
MessageBox.Show(String.Format(
"Error message{0}",
errorLine.ToString()), "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
Of course, this will stop the execution of this method, but I want to stop the execution of the main method (a button click method).
What is the best way to do this in C#?
You should really be using exceptions in C#, for example
private void Calculate(string[] lines)
{
try
{
lines.ForEach(Validate);
// process lines
}
catch(InvalidArgumentException ex)
{
MessageBox.Show(...);
}
}
private void Validate(string s)
{
if(s.IsNullOrEmpty)
throw new InvalidArgumentException(/* some details here*/);
}
You could write a validation method that returns true if the value is valid, and optionally return a string telling what is wrong:
private bool Validate(string s, out string error)
{
if (string.IsNullOrEmpty(s))
{
error = "s is null";
return false;
}
else
{
error = null;
return true;
}
}
Then call it:
string error;
if (!Validate(null, out error))
{
MessageBox.Show(error);
// Do something
}
Instead of the string you could use an enum if you want to structure the list of possible errors.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
C# cleanest way to write retry logic?
i having a function contains web service call to the server which fails sometime (unable to connect remote server error) due to some disturbance in network. The code is in try catch block. i want to rerun the web service call within try block so that the web call will be done successfully.
const int MaxRetries = 5;
for(int i = 0; i < MaxRetries; i++)
{
try
{
// do stuff
break; // jump out of for loop if everything succeeded
}
catch(Exception)
{
Thread.Sleep(100); // optional delay here
}
}
bool success = false;
int retry = 0;
while (!success && retry<3)
{
try{
// web service calls
success = true;
} catch(Exception) {
retry ++;
}
}
public void Connect()
{
Connect(1);
}
private void Connect(int num)
{
if (num > 3)
throw new Exception("Maximum number of attempts reached");
try
{
// do stuff
}
catch
{
Connect(num++);
}
}
You can put a loop around the try catch block like this:
bool repeat = true
while( repeat){
repeat = false;
try
{
...
}
catch( Exception )
{
repeat = true;
}
}
I think you have your answer here. I just wanted to add a couple of suggestions based on my abundant experience with this problem.
If you add logging to the catch block, you can ascertain how often the web service call fails, and how many attempts were made in all. (Maybe put a toggle in web.config to turn this logging off once the issue subsides.)
That information may prove useful in discussions with system administrators if, for example, the web service provider is within your organization, such as on an intranet.
In addition, if you find that the calls are still failing too often, you could introduce a delay in the catch, so that the retry is not immediate. You might only want to do that on the final attempt. Sometimes it is worth the wait for the user, who doesn't want to lose all the data they have just entered.
And finally, depending on the situation, you could add a Retry button to the UI, so that the user could keep trying. The user could choose to wait five minutes for the network problem to clear itself up, and click Retry.
Wrap the try/catch in a while loop. Set a flag on success to exit the while (or just break out). Make sure you have some sort of retry limit so it won't keep going forever.
while (true)
{
try
{
// call webservice
// handle results
break;
}
catch (TemporaryException e)
{
// do any logging you wish
continue;
}
catch (FatalException e)
{
// do any logging you wish
break;
}
}
If you want to limit the retries, change the termination condition on the while loop.
void Method()
{
do
{
try
{
DoStuff();
return;
}
catch (Exception e)
{
// Do Something about exception.
}
}
while (true);
}
If you find yourself wanting to do this frequently in your code, you might consider implementing a reusable class that encapsulates the "re-try when an error is encountered" logic. This way, you can ensure that the behavior is standardized throughout your code base, instead of repeated each time.
There's an excellent example available on Dan Gartner's blog:
public class Retrier<TResult>
{
public TResult Try(Func<TResult> func, int maxRetries)
{
return TryWithDelay(func, maxRetries, 0);
}
public TResult TryWithDelay(Func<TResult> func, int maxRetries, int delayInMilliseconds)
{
TResult returnValue = default(TResult);
int numTries = 0;
bool succeeded = false;
while (numTries < maxRetries)
{
try
{
returnValue = func();
succeeded = true;
}
catch (Exception)
{
//todo: figure out what to do here
}
finally
{
numTries++;
}
if (succeeded)
return returnValue;
System.Threading.Thread.Sleep(delayInMilliseconds);
}
return default(TResult);
}
}
Well, the easiest would be to copy the code to the catch-block, right?
Another approach could look like:
private void YourMethodThatTriesToCallWebService()
{
//Don't catch errors
}
public void TryToCallWebService(int numTries)
{
bool failed = true;
for(int i = 0; i < numTries && failed; i++)
{
try{
YourMethodThatTriesToCallWebService();
failed = false;
}catch{
//do nothing
}
}
}
You should put the entire catch block into a while statement:
while(retryCount < MAX_RETRY && !success)
{
try
{
//do stuff , calling web service
success = true;
}
catch
{
retryCount++
success = false;
}
}
In Python, there is this useful exception handling code:
try:
# Code that could raise an exception
except Exception:
# Exception handling
else:
# Code to execute if the try block DID NOT fail
I think it's useful to be able to separate the code that could raise and exception from your normal code. In Python, this was possible as shown above, however I can't find anything like it in C#.
Assuming the feature or one like it doesn't exist, is it standard practice to put normal code in the try block or after the catch block?
The reason I ask is because I have the following code:
if (!IsReadOnly)
{
T newobj;
try
{
newobj = DataPortal.Update<T>(this);
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
}
}
Which requires the normal code to be in the try block because otherwise if an exception was raised and subsequently handled, newobj would be unassigned, but it feels quite unnatural to have this much code in the try block which is unrelated to the DataPortalException. What to do?
Thanks
I would prefer to see the rest of the code outside the try/catch so it is clear where the exception you are trying to catch is coming from and that you don't accidentally catch an exception that you weren't trying to catch.
I think the closest equivalent to the Python try/catch/else is to use a local boolean variable to remember whether or not an exception was thrown.
bool success;
try
{
foo();
success = true;
}
catch (MyException)
{
recover();
success = false;
}
if (success)
{
bar();
}
But if you are doing this, I'd ask why you don't either fully recover from the exception so that you can continue as if there had been success, or else fully abort by returning an error code or even just letting the exception propagate to the caller.
Barbaric solution: create an Else class derived from Exception, throw an instance of it at the end of the try block, and use catch (Else) {...} to handle the other stuff.
I feel so dirty.
This will might get downvoted but doesn't c# have goto(note I have almost no c# knowledge so I have no idea if this works).
what about something like
try
{
...
}
catch(Exception ex)
{
...
goto Jump_past_tryelse
}
...//Code to execute if the try block DID NOT fail
Jump_past_tryelse:
...
C# does not have such a concept, so you are just left with three options,
put the else code inside the try.
put the else code outside the try catch block, use a local variable to indicate success or failure, and an if block around your else code.
put the else code in the finally block, use a local variable to indicate success or failure, and an if block arount you else code.
Allow me to repeat an idea from a similar StackOverflow question. You cannot do this directly, but you can write a method that encapsulates the behavior you need. Look at the original question to see how to implement the method (if you're not familiar with lambda expressions and Func delegates). The usage could look like this:
TryExceptRaise(() => {
// code that can throw exception
}, (Exception e) => {
// code to run in case of an exception
return (...);
}, () => {
// code to run if there is no exception
return (...);
});
Just put your "else" block before the catch. Then, it will only execute if code execution reaches that point:
try
{
fee();
fi();
foe();
fum();
/// put your "else" stuff here.
/// It will only be executed if fee-fi-foe-fum did not fail.
}
catch(Exception e)
{
// handle exception
}
Given that, I fail to see the use of try..catch...else unless there's something vital missing from the OP's description.
With C# version 7, you could use local functions to emulate this behaviour:
Example 1: (since C# version 7)
void Main()
{
void checkedCode()
{
try
{
foo();
}
catch (Exception ex)
{
recover();
return;
}
// ElseCode here
}
checkedCode();
}
If you prefer lambda syntax, you could also declare a run method
void Run(Action r) { r(); }
which only needs to be there once in your code, and then use the pattern for anonymous methods as follows
Example 2: (older C# versions and C# version 7)
Run(() => {
try
{
foo();
}
catch (Exception)
{
recover();
return;
}
// ElseCode here
});
whereever you need to enclose code in a safe context.
Try it in DotNetFiddle
Notes:
In both examples a function context is created so that we can use return; to exit on error.
You can find a similar pattern like the one used in Example 2 in JavaScript: Self-invoking anonymous functions (e.g. JQuery uses them). Because in C# you cannot self-invoke, the helper method Run is used.
Since Run does not have to be a local function, Example 2 works with older C# versions as well
You could do something like this:
if (!IsReadOnly)
{
T newobj = null;
try
{
newobj = DataPortal.Update<T>(this);
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
}
if (newobj != null)
{
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
}
that would be the empty statement like hits
try
{
somethingThatCanThrow();
}
catch(Exception ex)
{
LogException(ex);
return;
}
ContinueFlow();
if (!IsReadOnly)
{
T newobj;
bool Done;
try
{
newobj = DataPortal.Update<T>(this);
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
Done = true;
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
Done = false;
}
finally
{
if (newobj != null && Done == false)
{
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
}
}
I want to go once through a loop but only if an exception is thrown go back through the loop. How would I write this in C#?
Thanks
This smells of bad design to me. The general rule is: exceptions should not be used for flow control. There are a number of reasons for this; namely, there are usually better/more reliable methods that can be used to check things before an exceptions is thrown, and also it decreases efficiency.
Nonetheless, just for the sake of argument, you could do something like the following:
while (true)
{
try
{
// do stuff here
}
catch (MyException)
{
continue;
}
// all is good
break;
}
Again - this is not the recommended way. I would be happy to suggest something better if you could provide a bit more context/examples/
What about the following where you can set a retry count:
int tryCount = 0;
while (tryCount < 3)
{
try
{
someReturn = SomeFunction(someParams);
}
catch (Exception)
{
tryCount++;
continue;
}
break;
}
That really depends on what you're doing, and the type of exception being thrown. Many exceptions aren't something that would be fixed by just trying again with the exact same inputs/data, and thus looping would just keep generating the exception ad infinitum.
Instead, you should check for relevant exceptions and then handle them in an appropriate manner for those particular exceptions.
You could use Polly
and then you just need to configure the Policy with your exceptions and retry count:
var retryPolicy = Policy
.Handle<IOException>(x => x.Message.Contains("already exist"))
.Or<FormatException>()
.Retry(3);
and you use like this:
retryPolicy.Execute(() =>
{
throw new FormatException();
});
Why not call a function that actually does the loop, and have a catch after it that would call the function again.
private void loop() {
for(...) {
}
}
some other method:
try {
loop();
} catch(Exception e) {
loop();
}
Something like:
bool done = false;
while( ! done )
{
try
{
DoSomething();
done = true;
} catch(Exception ex)
{
HandleException(ex);
}
}
As Noldorin said, it smells like a bad design. You're using exceptions to control the flow of the program. Better to have explicit checks for the conditions that will cause you to repeat the operation.
So I am using this simple stuff :D
bool exceptionthrow = false;
while (!exceptionthrow)
{
try
{
value = Convert.ToInt32(Console.ReadLine()); //example
exceptionthrow = true;
}
catch (Exception)
{
exceptionthrow = false;
continue;
}
}
Hope it helps :)