I have a method that parses currency strings (such as "€4.00" or "$14.50"), but sometimes there is a parsing error, and it throws a FormatException.
What I want to do, is to send the string that couldn't be parsed (threw the exception) to a database.
try
{
string euroNumber = "€4.00";
// Will throw a FormatException
double parsedNumber = Double.Parse(euroNumber, NumberStyles.Currency);
}
catch (FormatException ex)
{
string stringThatThrewTheException; // should be "€4.00" in this case
// [Omitted] Sending to server logic
}
Is it somehow possible? Or should I use some kind of a hack?
Thank you in advance.
As BugFinder said, you can use TryParse:
double parsedNumber;
var result = Double.TryParse(euroNumber, NumberStyles.Currency, CultureInfo.CurrentCulture, out parsedNumber);
if (!result)
{
// send error
}
Another alternative is to move the string outside of the scope of the try block:
string euroNumber = "€4.00";
try
{
// Will throw a FormatException
double parsedNumber = Double.Parse(euroNumber, NumberStyles.Currency);
}
catch (FormatException ex)
{
// Have access to euroNumber here now
// [Omitted] Sending to server logic
}
Related
Here is my code. when the user clicks the "calculate" button, the code will execute it. However, if the user doesn't put any number, the exception throws and the error message will pop up. I wan't my error message says that "You forgot to put the number!" but the automatic message that says "Input string was not in a correct format" pops up. How to change the error message?
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
// Local variables
String num1;
String num2;
double number1;
double number2;
double result;
// Get the numbers from the textboxes
num1 = txtInput1.Text;
num2 = txtInput2.Text;
number1 = double.Parse(num1);
number2 = double.Parse(num2);
// Determine the user clicks the Addition radiobutton
if (rdbAdd.Checked)
{
// Add two numbers
result = number1 + number2;
}
else
{
// Determine the user clicks the Subtraction radiobutton
if (rdbSubtract.Checked)
{
// Subtract numbers
result = number1 - number2;
}
else
{
// Determine the user clicks the Multiply radiobutton
if (rdbMultiply.Checked)
{
// Multiply numbers
result = number1 * number2;
}
else
{
// Devide numbers when the user clicks the Devision radiobutton
result = number1 / number2;
}
}
}
// Display the result
txtDisplay.Text = result.ToString();
}
catch (Exception ex)
{
// Display an error message
MessageBox.Show(ex.Message);
}
}
To display your choice of messages...
MessageBox.Show("Your message goes here.")
The exception has it's own message, you should intercept the type of exception you are interested in and display your message approriate to the exception. If there is nothing in the text fields, then Double.Parse throws the exception (look at Double.Parse for the Exceptions it throws)
But if number2 is zero, and the user chooses to "divide", you will get a different exception (divide by zero).
Generally, you should validate your input, and simply using Double.Parse might be all you need. But typically, you need more. Also, if you intend to internationalize your application, you need to parse according to locale. See the link above, there is a method for localized parsing.
This is the default message of this exception which is a FormatException.
You can catch that kind of exceptions and then just display your own message:
try
{
.... your code ...
}
catch (FormatException ex)
{
//FormatException was thrown, display your message
MessageBox.Show("You forgot to put the number!");
}
catch (Exception ex)
{
// Some other kind of exception was thrown ...
MessageBox.Show(ex.Message);
}
You can have several "catch" clauses, one for each type of exception that you want to handle:
try
{
// Your code goes here
}
catch (DivideByZeroException ex)
{
MessageBox.Show("Cannot divide by zero! " + ex.Message);
}
catch (Exception ex)
{
// This is a generic exception
MessageBox.Show("Error: " + ex.Message);
}
You must order them from more specific to more generic.
may be you try this one, you cannot proceed if one of the txtInput1 and txtInput2 are null or Empty.
if(string.IsNullOrWhiteSpace(txtInput1.Text) == true)
{
MessageBox.Show("Your message goes here.");
return; // this is important, return if true
}
if(string.IsNullOrWhiteSpace(txtInput2.Text) == true)
{
MessageBox.Show("Your message goes here.");
return; // this is important, return if true
}
// then
. . . . . // proceed if no problem found
Here I'm struggling to work with catch block like I wanted to execute the catch block when the value type is a string.
Here I'm using dynamic type to accept all the type of values when the method will returns.
Now I wanted to execute the catch block when the method will return the string type.
Here my code is
dynamic paymentResult = null;
try
{
paymentResult = await ExecuteSquarePayment(db, checkoutViewModel);
}
catch (Exception ex) when (paymentResult is string)
{
return Content(HttpStatusCode.InternalServerError,
$"{Messages.DonationPaymentFailed} {checkoutViewModel.PaymentMethod} : {ex.ToString()}");
}
You don't need a catch block for this. try-catch is used to handle exceptions. If it is an expected behavior just test for the type:
dynamic paymentResult = null;
paymentResult = await ExecuteSquarePayment(db, checkoutViewModel);
if(paymentResult is string)
{
return Content(HttpStatusCode.InternalServerError, $"
{Messages.DonationPaymentFailed}
{checkoutViewModel.PaymentMethod} : paymentResult is a string");
}
If for some reason you really need to do it in a catch block you will have to throw an Exception:
dynamic paymentResult = null;
try
{
paymentResult = await ExecuteSquarePayment(db, checkoutViewModel);
if(paymentResult is string)
{
throw new Exception("The result was of type string");
}
}
catch (Exception ex)
{
return Content(HttpStatusCode.InternalServerError, $"
{Messages.DonationPaymentFailed}
{checkoutViewModel.PaymentMethod} : {ex.ToString()}");
}
I'm guessing that you check in ExecuteSquarePayment for the correct type of the argument, right? If so, why not simply use the catch block with out the type restriction. If the argument type is correct there won't be an error.
I don't see any different return for other types that the argument may be.
I guess, if the ExecuteSquarePayment method throws an exception, paymentResult will always be null(not set).
I am getting a weird error on run that I can't figure out. When I am in Visual Studio no error is thrown until I run the program. When I run it however I get an error saying that there was an unhandled exception on type. This is pertaining to the conversion of the field[0] to an int, any advice?
empReader = new StreamReader(fileName);
while (empReader.Peek() > -1)
{
string line = empReader.ReadLine(); //read a line from the text file
string[] fields = line.Split(',');
int idCheck = Convert.ToInt32(fields[0]);
empTempId.Add(idCheck);
}
empReader.Close();
If you're unsure whether or not the value will be an integer, use int.TryParse instead:
int idCheck;
if (int.TryParse(fields[0], out idCheck))
empTempId.Add(idCheck);
This prevents a runtime exception by trying to convert, then returning false if it cannot do so.
You can wrap it in a try/catch block.
try {
int idCheck = Convert.ToInt32(fields[0]);
Console.WriteLine("{0} --> {1}", fields[0], idCheck);
}
catch (FormatException) {
Console.WriteLine("{0}: Bad Format", fields[0]);
}
catch (OverflowException) {
Console.WriteLine("{0}: Overflow", fields[0]);
}
Consider I have a try block that contains 3 statements, and all of them cause Exceptions. I want all the 3 exceptions to be handled by their relevant catch blocks.. is it possible ?
something like this-->
class multicatch
{
public static void main(String[] args)
{
int[] c={1};
String s="this is a false integer";
try
{
int x=5/args.length;
c[10]=12;
int y=Integer.parseInt(s);
}
catch(ArithmeticException ae)
{
System.out.println("Cannot divide a number by zero.");
}
catch(ArrayIndexOutOfBoundsException abe)
{
System.out.println("This array index is not accessible.");
}
catch(NumberFormatException nfe)
{
System.out.println("Cannot parse a non-integer string.");
}
}
}
Is it possible to obtain the following output? -->>
Cannot divide a number by zero.
This array index is not accessible.
Cannot parse a non-integer string.
Is it possible to obtain the following output?
No, because only one of the exceptions will be thrown. Execution leaves the try block as soon as the exception is thrown, and assuming there's a matching catch block, it continues there. It doesn't go back into the try block, so you can't end up with a second exception.
See the Java tutorial for a general lesson in exception handling, and section 11.3 of the JLS for more details.
If you want to catch multiple exceptions, you have to split your code across multiple try/catch blocks.
A better approach is to validate your data and log errors without triggering Exceptions to do this.
To add to Jon's answer, while you won't catch multiple exceptions from a single try block, you can have multiple handlers handle a single exception.
try
{
try
{
throw new Exception("This is an exception.");
}
catch(Exception foo)
{
System.Console.WriteLine(foo.Message);
throw; // rethrows foo for the next handler.
}
}
catch(Exception bar)
{
System.Console.WriteLine("And again: " + bar.Message);
}
This produces the output:
This is an exception.
And again: This is an exception.
this is a REALY BAD PRACTICE, but you can do next (solve your problem using finally block):
private static void Main()
{
int[] c={1};
String s="this is a false integer";
try
{
int z = 0;
int x = 5/z;
}
catch (ArithmeticException exception)
{
Console.WriteLine(exception.GetType().ToString());
}
finally
{
try
{
c[10] = 12;
}
catch(IndexOutOfRangeException exception)
{
Console.WriteLine(exception.GetType().ToString());
}
finally
{
try
{
int y = int.Parse(s);
}
catch (FormatException exception)
{
Console.WriteLine(exception.GetType().ToString());
}
}
Console.ReadKey();
}
}
Showing all of the exceptions handling at once is impossible. The goal of each exception catch is to have a different handling for each Exception type and otherwise it's pointless to print them all together.
No ,
It will not execute all three catch statements. The TRY block checks for error and then the execution comes out of the TRY block. Then Suitable catch will be executed. In your case, The ArithmeticException is in the Top of the Exception Hierarchy. So it will Execute and then the program terminates.
If you give, Catch(Exception e) before ArithmeticException then Exception catch will be executed... Better read about the SystemException Hierarchies at MSDN
Is there a way to know what is passed to method when an exception is thrown.e.g; Convert.ToBoolean(string mystring) when it throws FormatException?
Here I want to know what was mystring when exception was thrown?
You have to capture the general exception (or FormatException) and assign your values to Exception.Data member. Or re-throw a new exception with your values.
using Exception.Data
How to add your extra information
catch (Exception e)
{
e.Data.Add("ExtraInfo", "More information.");
throw e;
}
How to catch
catch (Exception e)
{
if (e.Data != null)
{
foreach (DictionaryEntry de in e.Data)
Console.WriteLine(" The key is '{0}' and the value is: {1}",
de.Key, de.Value);
}
}
// Or simply re throw a new exception with your string...
catch (Exception ex)
{
throw new Exception("My string was" + yourString);
}
You can still get the value of the variables inside the catch block as long as its either the parameters or variables declared above the try block. You have to either catch specific exceptions such as argumentnullexception/formatexception or wrap individual operations within the method in a try/catch block, to know the context where the exception was thrown.
void Method(int i, string j)
{
bool p;
try
{
}
catch(FormatException e)
{
//value of i, j, p are available here.
}
}
The ideal way is to check for possible situations where exceptions (such as formatexceptions) are thrown and prevent them. They are expensive and interrupts the process flow.
You should just be using Boolean.TryParse. Then you can say
bool value;
if(!Boolean.TryParse(myString, out value)) {
// it didn't parse
}
// it parsed