Simple C# Windows App - Catch statement always executes no matter what - c#

Here's the code for the event handler involved:
private void textBox1_TextChanged(object sender, EventArgs e)
{
try
{
seed = Convert.ToInt32(this.Text);
}
catch (FormatException)
{
MessageBox.Show("Input string is not a sequence of digits.");
}
catch (OverflowException)
{
MessageBox.Show("The number cannot fit in an Int32.");
}
}
It's supposed to ensure a user doesn't type anything but a number allowable by Int32 into the text box, but the first catch statement executes EVERY time you try to type ANYTHING into the box. I've looked around but I can't seem to figure out why...

Probably because this.Text doesn't read from the input box, but rather the class the handler is defined in.
I believe what you want is:
try
{
seed = Convert.ToInt32(((TextBox)caller).Text);
}

It might be helpful to see the error message, using the following (temporarily of course):
catch (FormatException exception)
{
MessageBox.Show("Input string is not a sequence of digits."
+ "Exception message was: " + exception.getMessage());
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
try
{
seed = Convert.ToInt32(textBox1.text);
}
catch (FormatException)
{
MessageBox.Show("Input string is not a sequence of digits.");
}
catch (OverflowException)
{
MessageBox.Show("The number cannot fit in an Int32.");
}
}
Please use the above statement and it should work correctly. If you type in a number the first exception will not execute.

Related

Catch ElementClickInterceptedException in Selenium with C#

I'm trying to catch a ElementClickInterceptedException in C#, but it apppears I'm doing something wrong since it doesn't go to the catch code line when I get that exception while debugging. Strange thing is that if the test runs normally, it doesn't throw the exception at that point, but when it runs in debug mode, it does...
I try catching the exception because Selenium keeps throwing it and I don't know what to do to solve it.
Seems like I have been catching the wrong exception all along. Anyway, I'll leave the code that worked for me when I got a TargetInvocationException or ElementClickInterceptedException so anyone facing the same issue can solve it like I did:
public bool clickBtn(IWebElement btnElement)
{
bool result = false;
int attempts = 0;
while (attempts < 10)
{
try
{
waitForClickable(btnElement);
btnElement.Click();
result = true;
break;
}
catch (TargetInvocationException e)
{
}
catch (StaleElementReferenceException e)
{
}
attempts++;
Thread.Sleep(2000);
}
return result;
}
I think you can get rid of the second catch and it will work all the same :)
Also, I leave the code for the "waitForClickable" method:
internal void waitForClickable(IWebElement button)
{
try
{
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(button));
}
catch (NoSuchElementException e)
{
throw new NoSuchElementException("It wasn't possible to click the element.\n" + e);
}
}
I wrote a Click() method for my framework that takes care of exceptions, retries, etc. Also, you don't need the Thread.Sleep() in there since the WebDriverWait takes care of waiting for the element to be clickable already. In my code, I replaced the loop and counter with a pure timeout in seconds.
/// <summary>
/// Clicks the element.
/// </summary>
/// <param name="locator">The By locator for the desired element.</param>
/// <param name="timeOut">[Optional] How long to wait for the element (in seconds). The default is 10s.</param>
public void Click(By locator, int timeOut = 10)
{
DateTime now = DateTime.Now;
while (DateTime.Now < now.AddSeconds(timeOut))
{
try
{
new WebDriverWait(Driver, TimeSpan.FromSeconds(timeOut)).Until(ExpectedConditions.ElementToBeClickable(locator)).Click();
return;
}
catch (Exception e) when (e is ElementClickInterceptedException || e is StaleElementReferenceException)
{
// do nothing, loop again
}
}
throw new Exception($"Not able to click element <{locator}> within {timeOut}s.");
}

AccessViolationException on PropertyAccessor.GetProperty

I have a problem with my VSTO add in. On some random machines I recieve an AccessViolationException trying to use PropertyAccessor.GetProperty.
I couldn't find an explenation on the internet for why this exception accures.
Also it seems there is no way to catch this exception, i use a try catch block that catces (System.Exception), but it doesn't catch it and outlook crashes.
Any ideas on what can be the problem?
Decorate your method with the attribute
[HandleProcessCorruptedStateExceptions]:
[HandleProcessCorruptedStateExceptions]
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
try
{
//Do something...
}
catch (Exception ex)
{
//This is catching ALL exception types
//even AccessViolationException
//or OutOfMemoryException
}
}

btnSubmit_Click skipping try and going straight to catch (Exception ex)

I have two near identical forms on the site and only one of them works. On firing button click they're supposed to collect text from checkbox fields and email that information on. One of the forms try is completely ignored and the error message in catch is displayed
Using the working form on the new page still won't work makes me think there may be issues with the page, but deleting the aspx and aspx.cs pages and rewriting them when it may not be that serious is not something I want to do if it's not necessary. I've tried removing 'if (IsPostBack)' and 'if (LiabilityCheckBox.Checked == true)' on the form with issues among other things, but nothing seems to help.
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (IsPostBack)
{
if (LiabilityCheckBox.Checked == true)
{
// validate the Captcha to check we're not dealing with a bot
bool isHuman = ExampleCaptcha.Validate(CaptchaCodeTextBox.Text);
CaptchaCodeTextBox.Text = null; // clear previous user input
if (!isHuman)
{
lblCaptchaError.Visible = true;
lblCaptchaError.Text = "Incorrect Code. Please try again!";
}
else
{
try
{
//some code
lblRegMessage.Text =
("Registration Successful. Thank you for entering."
+ "Please click button below to finalise Payment and Registration.");
// Clear the textbox values
//Show Continue Button.
ContinueButton.Visible = true;
}
catch (Exception ex)
{
lblMessage.Text = ("Your registration failed to send, please try again");
}
}
}
else
{
lblMessage.Text = ("You must check the Liability check box to continue");
}
}
}
I am expecting the result of filling out the form to be the mail is sent and a message appears telling the user "Registration Successful. Thank you for entering."
What I am getting is this:
catch (Exception ex)
{
lblMessage.Text = ("Your registration failed to send, please try again");
}
As I checked, your code missing some closing brackets. Please check the brackets are properly closed and in the series.

try catch not working

I can't figure out how to get the try catch to work. Need to have an error message box pop up when a non number is entered in the text boxes.
private void btnAdd_Click(object sender, EventArgs e)
{
int x = int.Parse(txtIn1.Text);
int y = int.Parse(txtIn2.Text);
txtIn1.Text = x.ToString();
txtIn2.Text = y.ToString();
lstOut.Items.Add((x + y).ToString("N0"));
try
{
int.Parse(txtIn1.Text);
int.Parse(txtIn2.Text);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
With minimal modifications: move all the code into the try so it catches when any Exception is hit. You're encountering your exception outside of the try block. You are only going to ever see your catch triggered if something within the corresponding try block is throw an exception.
private void btnAdd_Click(object sender, EventArgs e) {
try {
int x = int.Parse(txtIn1.Text);
int y = int.Parse(txtIn2.Text);
txtIn1.Text = x.ToString();
txtIn2.Text = y.ToString();
lstOut.Items.Add((x + y).ToString("N0"));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
Edit: As suggested by commenters, I think this answer is incomplete without stating that a Try/Catch block is overkill in this instance.
A better approach would be to use the built-in TryParse method (which can return a boolean regarding the success of the parse attempt, and an output value). Here is one way you could accomplish this:
private void btnAdd_Click(object sender, EventArgs e) {
var xSuccess = int.TryParse(txtIn1.Text, out int x);
var ySuccess = int.TryParse(txtIn2.Text, out int y);
if(!xSuccess)
MessageBox.Show($"{x} could not be parsed to int!");
if(!ySuccess)
MessageBox.Show($"{y} could not be parsed to int!");
if(xSuccess && ySuccess)
lstOut.Items.Add((x + y).ToString("N0"));
}
You shouldn't use try-catch as a control block as explained in this SO post. Use if for that. Try catch is really meant to be used when you can't do otherwise or when something that you didn't expect happened.
You can use this SO post as an example and your code could look like this
private void btnAdd_Click(object sender, EventArgs e)
{
int x;
int y;
if(!int.TryParse(txtIn1.Text, out x) || !int.TryParse(txtIn2.Text, out y))
MessageBox.Show("Parse failed !");
}
You can use
Console.WriteLine(x);
Console.WriteLine(y);
to verify that the vars were properly given a value
For more information about the int.TryParse() method vs int.Parse() see this post
As other have mentioned, it's the first int.Parse() functions that are tripping things up - the ones outside the Try/Catch block.
I wanted to expand on the TryParse() function - and why should probably be using that.
Exceptions are expensive - they're a rather large overhead in terms of Time/CPU/etc. They're also not user-friendly. You want to say "Please enter a valid number" to the user, not "An exception occurred: ..."
Instead, you can use TryParse, which returns whether the parsing worked; the output of the parse is an "out" parameter in the inputs list:
int myValue;
bool parseWorked = int.TryParse("3", out myValue);
This doesn't have the Exception overhead - it runs quickly, regardless of whether the input's valid.
Why not use a different approach?
Use the TextBox.KeyPress event:
private void txtIn1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) /* || add more conditions*/)
e.Handled = true; // Prevent key to be added to the TextBox' text.
}
Now you don't have to check if there are non-numbers in your string.
Your statement int.Parse(txtIn1.Text); will surely work.

C# .Net Freeze while iterating through large number of files

I have a problem that I wrote an application that would iterate through files and add +1 to the integer each file, until it reaches a specific file name. The problem is probably because .Net does not access the native file system directly, it fills up collections, but in my case it would take years, believe me, I have 260 000 files in the target folder. The iteration does not even reach the second file. The thread just totally freezes, no errors, no exceptions. So is there any way to get a direct access to the Native File System without any useless collection filling ups?
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
try
{
foreach (string file in Directory.GetFiles("\\\\Mypcname-PC\\vxheaven\\malware"))
{
count++;
label1.Text = Convert.ToString(count);
if (file.Contains(textBox1.Text))
{
label1.Text = Convert.ToString(count) + " reached the file";
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
btw. Sorry for my bad english
Regards
Because you are doing all the work on the UI thread it can't refresh while it is working. You need to do the work on a background thread then update the UI in a thread safe way. Also switching to Directory.EnumerateFiles will make it faster to read the first file so it does not need to store all the records in to an array. Lastly I changed ex.Message to ex.ToString(), it will display much more useful information that way.
private async void button1_Click(object sender, EventArgs e)
{
try
{
var text = textBox1.Text;
var progress = new Progress<string>((x) => label1.Text = x);
await Task.Run(() => DoWork(progress, text));
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void DoWork(IProgress<string> progress, string text)
{
foreach (string file in Directory.EnumerateFiles("\\\\Mypcname-PC\\vxheaven\\malware"))
{
count++;
progress.Report(Convert.ToString(count));
if (file.Contains(text))
{
progress.Report(Convert.ToString(count) + " reached the file");
break;
}
}
}
(Code was written in a web browser from memory so there may be errors)
Seems like you are using a potentially very time-consuming loop without ever processing the Windows message queue, therefore your application may APPEAR to be frozen, while it's probably just busy doing what you instructed it to do in the loop. Try this:
private void button1_Click(object sender, EventArgs e)
{
try
{
foreach (string file in Directory.GetFiles("\\\\Mypcname-PC\\vxheaven\\malware"))
{
count++;
label1.Text = Convert.ToString(count);
Application.DoEvents();
if (file.Contains(textBox1.Text))
{
label1.Text = Convert.ToString(count) + " reached the file";
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

Categories

Resources