I want to test if my decimal Add is smaller than MAXVALUE and bigger than MINVALUE, with a Try... Catch Method. And if the numbers are bigger than MAXVALUE or smaller than MINVALUE the code should throw an Exception.
But my Code isn't working.
public static decimal Add(decimal number1, decimal number2)
{
decimal Add = number1 + number2;
try
{
Add > RESULT_MAXVALUE;
Add < RESULT_MINVALUE;
}
catch(Exception)
{
//Do Stuf
}
}
I don't want to use if... else!
It depends on the language that you're using, but the convention is that the try block contains statements that can throw exceptions, and thrown exceptions are caught by the catch() blocks following the try. You need to explicitly throw an exception before it can be caught.
It looks like you're using C#. Consider reading https://msdn.microsoft.com/en-us/library/0yd65esw.aspx for more information about try-catch statements in C#.
Using exceptions in your case may not be necessary. Consider using an if statement, like this:
decimal result = a + b;
if ((result > MAX_VALUE) || (result < MIN_VALUE))
{
// Do stuff.
}
But to answer your question more directly, here's how you would do it using exceptions:
decimal result = a + b;
try
{
if ((result > MAX_VALUE) || (result < MIN_VALUE))
{
throw new System.ArithmeticException(); // Or make an exception type.
}
}
catch (System.ArithmeticException e)
{
// Do stuff.
}
Or perhaps you would throw the exception in Add, but not catch it. Then it would be the caller's responsibility to handle the exception, or let the program crash. That would look like this:
// Adds two numbers. Throws a System.ArithmeticException if the result
// is greater than MAX_VALUE or less than MIN_VALUE.
public static decimal Add(decimal a, decimal b)
{
decimal result = a + b;
if ((result > MAX_VALUE) || (result < MIN_VALUE))
{
throw new System.ArithmeticException(); // Or make an exception type.
}
}
And callers would need to wrap calls to Add in a try {} catch if they expect some results to be bigger than MAX_VALUE or less than MIN_VALUE (or, callers could not catch the exception and the program would crash).
Related
I'm trying to write an NUnit test to check that my extension method throws an exception when called with a negative parameter, what i want is to execute the first two if condition to check the parameters without enumerating the soruce "infiniteSeq", not even partially.
I want this test to have success without using a toList or something to force the enumeration.
Assert.That(()=> infiniteSeq.Smooth(-1), Throws.TypeOf<ArgumentOutOfRangeException>());
This is my extension method, it must never end, if it does then the source is finite and it throws a FiniteSourceException.
public static IEnumerable<double> Smooth(this IEnumerable<double> s, int N)
{
if (N < 0) throw new ArgumentOutOfRangeException(nameof(N), "Is negative");
if (s is null) throw new ArgumentNullException(nameof(s), "is null");
while (true)
{
List<double> buffer = new List<double>();
using (var seqEnumerator = s.GetEnumerator())
{
int index = 0;
while (seqEnumerator.MoveNext())
{
buffer.Add(seqEnumerator.Current);
//Enough items to start Smoothing
if (buffer.Count >= N*2)
{
List<double> elementForAvg;
try
{
int startIndex = (index-N<0) ? 0 : index-N;
int endIndex = index+N;
elementForAvg = buffer.GetRange(startIndex,endIndex);
}
catch (Exception e)
{
if (e is ArgumentException)
throw new FiniteSourceException();
throw;
}
yield return AvgCalculator(elementForAvg);
index++;
}
}
throw new FiniteSourceException();
}
Is this possible?
If you're concerned about invoking an infinite loop, you could always perform a single iteration which will execute the if statements:
Assert.That(
() => infiniteSeq.Smooth(-1).GetEnumerator().MoveNext(),
Throws.TypeOf<ArgumentOutOfRangeException>());
An alternative approach would be to alter the behaviour of Smooth to throw immediately rather than after the first iteration.
You could do this by returning an iterator instead of using yield within the body of Smooth:
public static IEnumerable<double> Smooth(this IEnumerable<double> s, int N)
{
if (N < 0) throw new ArgumentOutOfRangeException(nameof(N), "Is negative");
if (s is null) throw new ArgumentNullException(nameof(s), "is null");
return Iterator();
IEnumerable<double> Iterator()
{
while (true)
{
//...
yield return AvgCalculator(elementForAvg);
//...
throw new FiniteSourceException();
}
}
}
In the above example, the yield keyword is used within the Iterator local method rather than Smooth, meaning Smooth is no longer an iterator and it's body will execute at the point of call rather than being deferred.
In a case like this, where you want to "fail fast", before any enumeration has been executed, you can break the method up into two, using an inner function or lambda. Something like this:
public static IEnumerable<double> Smooth(this IEnumerable<double> s, int N)
{
if (N < 0) throw new ArgumentOutOfRangeException(nameof(N), "Is negative");
if (s is null) throw new ArgumentNullException(nameof(s), "is null");
return Smooth();
IEnumerable<double> Smooth()
{
while (true)
{
// ...
yield return s.MoveNext();
}
}
}
The net effect will be that the arguments will be checked before the enumeration begins, throwing an exception at the time the call is made. The original way will cause the validation exceptions to be thrown from where the return value is first enumerated, potentially causing strange errors in unexpected locations.
I am getting this error after using catch-try in my code. When I hadn’t used the try-catch in my code then editor would not give this error, but when I closed my program in try-catch code then it started giving this error. My code is given bellow.
try
{
month = Int32.Parse(Console.ReadLine());
}
catch (FormatException ee)
{
Console.WriteLine(ee.Message);
}
if (month > 12 || mnth < 0)
{
Console.Write("----Incorrect Month...plz Re-");
lp_val = 1;
}
Problem : you declared a variable mnth but didnot intialize it.so if the user input is not a valid integre as input Parse function throws exception and variable mnth still is not initialized.
Solution : initialize variable mnth at the time of declaration.
Try This:
try
{
mnth=0;
mnth = Int32.Parse(Console.ReadLine());
}
catch (FormatException ee)
{
Console.WriteLine(ee.Message);
}
if (mnth > 12 || mnth < 0)
{
Console.Write("----Incorrect Month...plz Re-");
lp_val = 1;
}
OR
You can move your if block inside the try block.
try
{
mnth=0;
mnth = Int32.Parse(Console.ReadLine());
if (mnth > 12 || mnth < 0)
{
Console.Write("----Incorrect Month...plz Re-");
lp_val = 1;
}
}
catch (FormatException ee)
{
Console.WriteLine(ee.Message);
}
First off, you have two variables, month, and mnth. It looks like this is just wan error when created by posting the question here, but if it is not, make sure you resolve any typos in your code.
If an exception is raised by Int32.Parse the result will never be assigned to month, so it's not guaranteed to be assigned when you're evaluating the condition later.
The solution is to initialize the variable outside the the try block:
int month = 0;
Or to use Int32.TryParse instead of wrapping it in a try/catch:
int month;
if (!Int32.TryParse(Console.ReadLine(), out month))
{
Console.WriteLine("Unable to parse input");
}
Apart from the fact that you have variables named month and mnth, if the try-block code throws an exception, the line is not executed and mnth is not initialized to any value.
Looks like you declare month variable but you didn't initialize it.
This code gives the same error with your code;
int month;
if(month < 12)
{
//
}
That's why you should initialize it before you use it. For example use;
int month = 0;
instead
int month;
I am trying to create a function for a calculator. I want the program to try to parse a string given to transform it to an double number. My function has the following form:
private double readOperator(String stringOper)
{
try
{
double oper;
oper = double.Parse(stringOper);
return oper;
}
catch (Exception ex)
{
MessageBox.Show("Wrong Input");
throw ex; // Without this I have to return a double value (no null allowed)
}
}
PROBLEM: I need the function to return a double value so to be able to access it on from the main program as a double. But if the parsing fails (it has chars inside) the only way to get buy the debuger is to either return a double value (not good as the user must be able to input whatever double value he wishes) or to throw an exception which freezes the program.
I don't really need any kind of handling instead of informing the user to change his input, as it is a form. But by throwing the exception the program crashes (as it should). If I continue to run the program by allowing Windows to do so when they ask me everything runs as I want to run. But obviously I don't want the user to go through this process!
Solution: how can I handle the throwing of this exception not to crash the program (to do nothing at all) or how could I return a null/special type of value to handle this? Using public variables is not a good programming method which can easily solve this issue
So handle it (to inform user is handling the exception) in main method:
static void main()
{
try
{
Console.Write("Enter first operand: ");
double a = readOperand(Console.ReadLine());
Console.Write("Enter second operand: ");
double b = readOperand(Console.ReadLine());
// Do something with them
}
catch (FormatException)
{
Console.WriteLine("You didn't enter a floating point number.");
}
}
Or, better, do not even throw exceptions (it's a good practice if you can avoid them: invalid user input isn't an exceptional situation):
double a;
if (!Double.TryParse(Console.ReadLine(), out a))
Console.WriteLine("You didn't enter a floating point number.");
In case your input validation is something more (for example range checking too) than a Double.TryParse() (and you want to keep it in a separate function) then you have two options:
return a nullable value (double? in this case) where null means invalid input.
mimic TryParse behavior and prototype: bool TryReadOperand(string operand, out double value). Simply return false for invalid inputs (decide where to output error message, I would suggest Main because it's more common).
First of all, consider using the TryParse method. Secondly the simplest solution is to return double? from your method, and interpret null as parsing failure. However in general returning null as a "special value" is not considered a good design.
Why not just throw an exception (like you do now), and catch and handle it in a place when you call readOperator method?
The way I see it you have two options.
Try catch around every instance of readOperator() and handle the invalid input in that catch statement.
change it to private double? readOperator(string stringOper). double? is double that allows null values so it would be fine to return null.
The following transforms a nullable double into a normal one
//where d is a double?
if (d.HasValue) //Returns true if not null
{
double x = d.Value // Returns the double value of the double? if not null otherwise throws exception
}
else
{
// Handle the null value
}
edit: Kind of duped another user's answer while writing but I'm going to leave mine here for the example
TryParse is a good bet:
private double readOperator(String stringOper)
{
double oper;
if (Double.TryParse(stringOper, out oper))
return oper;
MessageBox.Show("Wrong Input");
return 0;
}
Also, when you throw an exception using throw ex; you're losing your stack trace.
catch (Exception ex)
{
MessageBox.Show("Wrong Input");
throw; // <---- retains stack trace
}
I currently got the following method, which is returning me percent-values. For example for an item-price of $350,000 and a percentage of 7%, it returns 24,500.
public static decimal GetPercentValue(decimal? percentage, decimal baseValue)
{
decimal result = 0m;
if (percentage != null)
{
try
{
result = Convert.ToDecimal(baseValue * percentage / 100m);
}
catch (OverflowException)
{
result = 0;
Logger.Warn("OverflowException caught in GetPercentValue() - should better be handled UI-Sided!");
}
}
return result;
}
I don't think this is handled the right way, so is there any way to avoid an exception in this situation?
An OverflowException is being thrown when a user enters an insane number like 999,999,999,999,999,999 and calculates 9999999999% of it. This way I can't check percentage or baseValue for <= decimal.MaxValue simply because they aren't... The calculation result itself then exceeds the decimal range.
This is an old question, but I ran into a similar issue, and thought to provide a possible alternate solution. The problem happens when some calculation of two numbers produces a number greater than a MaxValue. This causes an exception, and is hard to test in the usual way:
decimal existingValue = decimal.MaxValue;
decimal newValue = (decimal)100;
//doesn't work -- exception thrown here
if(existingValue + newValue <= decimal.MaxValue)
{
}
The solution that seems to work for me (without using a Try-Catch block) is to rewrite the equation, in this case as a subtraction:
if(decimal.MaxValue - existingValue >= newValue)
{
//DoSomething
}
MaxValue isn't exceeded because of the subtraction. I haven't tried a multiplication/division example, but I'm guessing it would work too.
The error handling should (most likely) be done outside the method. Right now you're hiding exceptions and returning wrong results (0 is returned when an error occures). The caller of your method cannot tell if the result is correct or if it's due to an OverflowException.
I'd rewrite the method like that:
public static decimal GetPercentValue(decimal? percentage, decimal baseValue)
{
if (percentage == null)
return 0;
return baseValue*(percentage.Value/100);
}
And optionally add a validation method that the user can call to check the parameters before calling the real method.. validation errors could be displayed in the UI:
public static string ValidatePercentValue(decimal? percentage, decimal baseValue)
{
try
{
GetPercentValue(percentage, baseValue);
return null;
}
catch (Exception ex)
{
return ex.Message;
}
}
Besides that note that...
baseValue*(percentage.Value/100)
... is better than...
baseValue*percentage.Value/100
Try to calculate 100% of decimal.MaxValue. The first one works while the second one throws an OverflowException.
In C# how to handle an invalid argument type exception before it occurs
static class calc
{
public static double subtract(double num1, double num2)
{
// I want to handle arguments exception here so whenever a nethod is called I can handle the exception
return num1 - num2;
}
}
I want to handle exception if the user use wrong arguments' type.
In the case of your example, how could the arguments be invalid? Since you state the types, the values cannot be invalid.
The only scenario I can think of is if the (num1 - num2) < Double.MinValue in which case this would cause an error.
verify that the parameters you are passing are actually valid types BEFORE you call the method.
Alternatively, Catch the exception using a try and catch around the call.
try
{
//Call Method
subtract(1.0,2.0);
}
catch (Exception ex)
{
throw new FaultException(ex.Message);
// Or display a message box.
}
The only way I can see for this method to fail would be :
1) You call this method by reflection, but with bad parameters. This wouldn't be an argument exception since the problem would be "outside the call".
2) You call the function with such parameters that double - double != double. This wouldn't be exception if the user use wrong arguments' type though. For this, you can check your argument against double.Min :
static class calc
{
public static double subtract(double num1, double num2)
{
double doubleAmountLeft = double.MaxValue - num1;
if (num2 > num1)
{
throw new ArgumentOutOfRangeException("num2 > double.MaxValue - num1.");
}
return num1 - num2;
}
}
Do you mean something like, for example, this?
static class calc
{
public static double subtract(double num1, double num2)
{
if (num1<num2) throw new ArgumentException("num1 < num2", "num2");
return num1 - num2;
}
}
You can't even compile this as accepting something that isn't double or can be converted to double. However, since compiling may happen close to execution (e.g. when the calling code is in an .aspx file), there is a bit of a point to this sometimes. It can also be convenient in such cases to have a form that accepts object parameters anyway so that the casting with the results of DataBinder.Eval doesn't have to be done on-page:
static class Calc
{
public static double Subtract(double num1, double num2)
{
return num1 - num2; //always correct type
}
public static double Substract(object num1, object num2)
{
try
{
return Subtract((double)num1, (double)num2);
//alternatively allowing looser matching:
//return Subtract(Convert.ToDouble(num1) - Convert.ToDouble(num2));
}
catch
{
throw new Exception("My Custom Exception Text");
}
}
}
Frankly though, I'd find this more confusing than the default behaviour if I pass the wrong type from on-the-fly compiled code like that in .aspx as I'd know the common exceptions better than yours.