I'm specifically looking for a solution for a console app, however answers for form apps are also welcome.
Would you be so kind as to help me with the following problem?
My Problem:
I want to create my own Exception that will catch any number from 5 to 9 when a user types one of them.
NOTE: I know I can solve this problem by simply playing with IF ELSE statements but I'm specifically looking for it to be CATCHed as Exception.
What I don't understand:
Once the user types in 5 for example, my own created exception catches it - What I don't understand is how to tell my created Exception Class what to catch, what to look for? Where do I type these numbers in my Exception and tell my Exception class that those numbers are exceptions?
If I wasn't clear enough, please let me know, I will try to rephrase myself.
You may benefit from an Exception tutorial.
It sounds like you are trying to do three things.
1 Read a number from a text input field.
2 Determine whether that is a valid number.
3 If the number is invalid, throw an exception.
//Read input
int i = -1;
i = int.TryParse(MyTextField.Text, out i);
if (i >= 5 && i <= 9)
throw new ArgumentOutOfRangeException("value", "Value cannot be between 5 - 9.");
Exceptions don't just happen. When your code throws an exception, for example if you try to divide by 0 and you get a DivideByZeroException - it means that some code somewhere has to have a line like throw new DivideByZeroException(); . (Admittedly, this is a simplification of the matter.)
So in order to throw the exception you want - you have to test the input and if it's not good then throw an exception.
And assuming you don’t mean that you need a custom Exception (e.g. FiveToNineException) - you can just use this:
if (i >= 5 && i <= 9)
{
throw new Exception("5 to 9 Exception");
}
Or:
if (i >= 5 && i <= 9)
{
Exception e = new Exception("5 to 9 Exception");
e.Data.Add("The number ", i);
throw e;
}
EDIT
For a very simple custom exception:
public class FiveToNineException : System.Exception
{
public FiveToNineException() : base() { }
}
and then you can have:
throw new FiveToNineException();
And:
try {/*Do something*/ }
catch (FiveToNineException ex) { }
For more information see this link for an answer to a question of mine.
If I understand you correct I think you should try something like:
if (yourNumber >= 5 && yourNumber <= 9)
{
throw new YourException(..);
}
But also see the comments. Your understanding of exceptions isn't correct.
The below code shows the basic example of a CustomException
class Program
{
static void Main(string[] args)
{
try
{
int x = Convert.ToInt32(Console.ReadLine());
if (x >= 5 && x <= 9)
{
CustomException e = new CustomException("Please Eneter Another Number");
throw e;
}
}
catch (CustomException ex)
{
Console.WriteLine(ex.Message);
}
}
}
public class CustomException : System.Exception
{
public CustomException(string txt)
: base(txt)
{
}
}
Related
Created a simple program using Linqpad, where I am throwing an exception explicitly in the Parallel Foreach loop, which ideally shall be caught in the caller as Aggregate Exception, but when I explicitly throw the exception, it sometimes skip out few exceptions on random basis. I am not able to understand the behavior, anyone who can explain:
void Main()
{
try
{
var intList = new List<int> {1,2,3,4,5,6};
Parallel.ForEach(intList, i => Test1(i));
}
catch (AggregateException aggregateException)
{
foreach (var ex in aggregateException.Flatten().InnerExceptions)
{
ex.Message.Dump();
}
}
}
public void Test1(int i)
{
try
{
if (i % 2 != 0)
throw new Exception($"{i} - Odd value exception");
}
catch(Exception ex)
{
ex.Message.Dump();
throw;
}
}
public void Test2(int i)
{
if (i % 2 != 0)
throw new Exception($"{i} - Odd value exception");
}
public void Test3(int i)
{
try
{
if (i % 2 != 0)
throw new Exception($"{i} - Odd value exception");
}
catch(Exception ex)
{
ex.Message.Dump();
}
}
Details:
There two versions of Test, one with explicit Try Catch and other without
Both have similar inconsistent behavior to the extent that in Test1, even local try catch doesn't print the value
There can be third version Test3 which always work as exception is not explicitly thrown out of the parallel loop
Dump is a linqpad print call replace it by Console.WriteLine on the visual studio
There's an option define here, which collects all exceptions in a ConcurrentQueue and throw them later as aggregated exception, but why the current code doesn't work as expected, I am not very sure. In this case we expect Output to be:
1 - Odd value exception
3 - Odd value exception
5 - Odd value exception
but some of them are randomly skipped, that too in a simple program, there are much more miss in a complex program, which do far more work
This is entirely expected behaviour.
See the docs,
an unhandled exception causes the loop to terminate immediately
When you throw an exception, no new Tasks will be scheduled.
So the behaviour will appear unpredictable. You have no right to expect that all subtasks will execute. That is not the contract of a Parallel.For loop.
The difference will be much clearer when you add more items to the source list.
The output will always show a number of exceptions in the neighbourhood of ThreadPool.MinThreads.
I am trying to get the ideal way to handle exception. I googled & read that I should put try catch in the catch block as well to handle but what if any exception occurs in the nested block itself.
try
{
int a = 10;
int b = 0;
int c = a / b;
Console.WriteLine(c);
Console.ReadKey();
}
catch (Exception ex)
{
int a = 10; int b = 0;
int c = a / b;
Console.WriteLine(ex.Message.ToString());
Console.ReadKey();
}
finally
{
Console.WriteLine("Some Exception");
}
On googling I read that it should be decorated as below:
If exception occurs in Catch block itself then how to handle it in C#?
If exception occurs in Catch block itself then how to handle it in C#?
What happens if an exception occurs in Catch block in C#. Also what would be the caller result in that case
try
{
int a = 10;
int b = 0;
int c = a / b;
Console.WriteLine(c);
Console.ReadKey();
}
catch (Exception ex)
{
try
{
}
catch(Exception innerEx)
{
// What if exception here also occurs.
}
}
finally
{
Console.WriteLine("Some Exception");
}
If I do this way, then it will stuck in an infinite try-catch block.
I think there would be some better or the right way to handle this scenario.
I think there would be some better or the right way to handle this scenario.
No snark intended in this but simply, don't allow an exception to happen in the first place.
A try...catch is a language construct that ensures you handle an edge case or error you didn't mitigate and design for in the first place, hence why it's exceptional code.
In your code, you're simply throwing an error because of a division by 0, but in the real-world, you want to handle that and alert the user (or developer, or server, or whatever), and then handle the actual exceptional code, example:
static void PrintError()
{
Console.WriteLine("You must enter a valid number between {0} and {1}, excluding 0", int.MaxValue, int.MinValue);
}
static void Main(string[] args)
{
try {
int a = 10;
int b = 0;
PrintError(); // Tell user to enter valid numbers
while (b == 0) {
string user_input = Console.ReadLine();
if (int.TryParse(user_input, out b)) { // is it an actual number?
if (b == 0) { // no 0's remember user!??
PrintError();
} else {
// ok, everything checks out, so do what the system can actually handle without throwing an error
Console.WriteLine("a/b = {0}", (a / b));
}
} else {
PrintError();
}
}
} catch (Exception ex) {
Console.WriteLine("Something exceptional happened: {0}", ex);
}
}
This example could be simplified further, but it demonstrates there isn't an exception that could actually occur except something that is actually exceptional (i.e. out of memory error or some other system error).
In the event of larger code bases with multiple classes, the exception handler and finalizer would be where you could clean up resources acquired in other areas of the code, like closing a socket or file handle to ensure data is not lost.
In the event an error happens in the exception handler (something that can and does happen), you need to be aware of that and know what might happen in that case.
In the event of a C# application utilizing the .NET framework, an exception thrown within an exception will just cause the application to crash with the inner exception stack trace (versus the "outer" exception that's probably more relevant to the actual exception) if not handled.
There's plenty of "wrong" ways to handle exceptions (like not handling them at all), but there's not really a "right" way given the variable nature of exceptions.
Hope that can help.
First of all you need to know what does try,catch and finally works lets start:
Try: In this block we can write code which have the possibilities to throw some error (Better practice is to write code part in it.)
Catch: It is responsible to show error and what to do if error arises(Like in your code 10/0 throws error which can be handled in this section.)
Finally: Code written in this part will execute any how weather any error comes in or not.
Now for your query it would be better that you can use If...else in finally and code put in that part would be kept in try catch block.
For example:
bool flagCatch=false;
try
{
int a = 10;
int b = 0;
int c = a / b;
Console.WriteLine(c);
Console.ReadKey();
}
catch (Exception ex)
{
//Error handling
flagCatch=true;
Console.WriteLine(ex.Message.ToString());
Console.ReadKey();
}
finally
{
try
{
if(flagCatch)
{
//Code
}
else
{
//Code when error not comes
}
}
catch(Exception err)
{
//Error handling
}
}
I would go with the comment of Tieson T. . From my point of view it is an design issue.
I could also build an example with if statements -> if that goes wrong, I perform failure handling -> if the failure handling goes wrong, I perform failure handling, If the failure handling goes wrong ....
To make the code more readable, you can try to "hide" the try-catch blocks in method like:
static void PerformInTryCatch<T, TException>(Action<T> action, T obj) where TException : Exception
{
try
{
action(obj);
}
catch (TException exception)
{
// Perform some logging
}
}
Hope that helps.
Based on this question (What benefit does the new Exception filter feature provide?).
The statement:
Exception filters are preferable to catching and rethrowing because
they leave the stack unharmed. If the exception later causes the stack
to be dumped, you can see where it originally came from, rather than
just the last place it was rethrown.
after doing some testing, I did not see the difference between both, the old and the new, I still see the exception from the place it was rethrown. So, or the information is not confirmed, I don't understand the Exception filters( that is why I am asking), or I am doing it wrong. Can you explaing me why this action filter are an advantage?
class specialException : Exception
{
public DateTime sentDateTime { get; } = DateTime.Now;
public int code { get; } = 0;
public string emailsToAlert { get; } = "email#domain.com";
}
then:
try
{
throw new specialException(); //line 16
throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e) when(e.code == 0)
{
WriteLine("E.code 0");
throw; // <-Line 23
}
catch (FormatException e)
{
WriteLine("cond1 " + e.GetBaseException().Message+" "+e.StackTrace);
throw;
}
catch (Exception e) //when (cond2)
{
Console.WriteLine("cond2! " + e.Message);
throw;
}
Result:
The advantages of exception filtering are more to do with when the filter doesn't match, not when it does match. If you remove all of the catch blocks except for the first one, and change the filter on the first catch block to when(e.code != 0), then the callstack of the exception would indicate it was thrown on line 16.
The old way of implementing this would be as follows:
try
{
throw new specialException(); //line 16
throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e)
{
if(e.code != 0)
{
WriteLine("E.code isn't 0");
return;
}
throw;
}
In this case, the call stack will indicate that the exception was thrown at the throw statement, rather than on line 16.
I'll give you a good real world example that I've used it for: deadlock retry loops.
Some APIs are nice and have a specific DeadlockException sort of thing -- others, like SOAP proxies, not quite. When you don't have one, exception filters are great to avoid needing to rethrow.
int retryCount = 0;
while(true)
{
try
{
// do stuff.
break;
}
catch(Exception ex) when(ex.Message == "Deadlock" && ++retryCount < 10)
{
// retry up to 10 times.
continue;
}
}
This saves you from having to throw a wrapper exception if a non-deadlock exception happens, or if the retry limit is hit.
I'm working on unit-tests for an application which has a constructor that takes three values as arguments. The numbers shall be 0 or higher, and now I'm writing on an unit-test for the constructor that throws an exception if this is not the case.
What I can't figure out is how I what to write after "Assert" to determine this so that the test passes if illegal numbers are passed to the constructor. Thanks in advance.
EDIT: I'm using MSTest framework
public void uniqueSidesTest2()
{
try {
Triangle_Accessor target = new Triangle_Accessor(0, 10, 10);
}
catch (){
Assert // true (pass the test)
return;
}
Assert. // false (test fails)
}
// From the code...
public Triangle(double a, double b, double c) {
if ((a <= 0) || (b <= 0) || (c <= 0)){
throw new ArgumentException("The numbers must higher than 0.");
}
sides = new double[] { a, b, c };
}
First of all, you should throw an ArgumentOutOfRangeException rather than just an ArgumentException.
Second, your unit test should expect an Exception to be thrown, like so:
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public static void MyUnitTestForArgumentA()
{
...
}
So, you need to create separate unit tests -- one for each argument -- that test whether the method throws a correct exception when the argument is out of range.
No need to use a try catch block. Using NUnit or the MSTest framework you can use an attribute on your test method declaration to specify that you expect an exception.
MSTest
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void uniqueSidesTest2()
It may not be the best solution, but if I'm testing to make sure an Exception is thrown, I will do something like the following:
public void uniqueSidesTest2()
{
try {
Triangle_Accessor target = new Triangle_Accessor(0, 10, 10);
Assert.Fail("An exception was not thrown for an invalid argument.");
}
catch (ArgumentException ex){
//Do nothing, test passes if Assert.Fail() was not called
}
}
Since your constructor call should throw an error, if it ever gets to the second line (The Assert.Fail() line) then you know it didn't properly throw the exception.
If you don't have nunit (or other framework that has this support built in you can use the following type of helper method
public static void ThrowsExceptionOfType<T>(Action action) where T: Exception
{
try
{
action();
}
catch (T)
{
return;
}
catch (Exception exp)
{
throw new Exception(string.Format("Assert failed. Expecting exception of type {0} but got {1}.", typeof(T).Name, exp.GetType().Name));
}
throw new Exception(string.Format("Assert failed. Expecting exception of type {0} but no exception was thrown.", typeof(T).Name));
}
Your test would look like this
AssertHelper.ThrowsExceptionOfType<ArgumentException>(
() =>
{
new Triangle_Accessor(0, 10, 10);
});
You will not need an Assert in the catch (but you might want to catch a more specific exception, like ArgumentException).
To always fail, there is an Assert.Fail.
You don't mention what framework you are using for unit testing, but I think what you're looking for is something like what is shown here:
http://www.nunit.org/index.php?p=exception&r=2.4
the question was :
The application should ask the user for the total number of tickets to be booked. while the booking the tickets if the total number of booked tickets exceeds the available tickets, the application should raise an exception. I don't know why it is not showing an error when I do this I came up with this solution:
using System;
namespace Ticket
{
class blah
{
public void abc()
{
int numberOfTickets;
int numberOfAvailableTickets=10;
int cost = 100;
int pay;
Console.WriteLine("how many tickets do you need");
numberOfTickets = Convert.ToInt32(Console.ReadLine());
try
{
if (numberOfTickets < numberOfAvailableTickets)
{
pay = 100 * numberOfTickets;
Console.WriteLine("Pay please");
Console.WriteLine(pay);
}
}
if( numberOfTickets>numberOfAvailableTickets)
{
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
class Theater
{
static void Main(string[] args)
{
blah hi = new blah();
hi.abc();
Console.ReadLine();
}
}
}
I am not even sure that the code you show even compiles... try this
using System;
namespace Ticket
{
class blah
{
public void abc()
{
int numberOfTickets;
int numberOfAvailableTickets=10;
int cost = 100;
int pay;
Console.WriteLine("how many tickets do you need");
numberOfTickets = Convert.ToInt32(Console.ReadLine());
try
{
if( numberOfTickets>numberOfAvailableTickets)
throw new Exception ("Not enough Tickets available!");
pay = 100 * numberOfTickets;
Console.WriteLine("Pay please");
Console.WriteLine(pay);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
class Theater
{
static void Main(string[] args)
{
blah hi = new blah();
hi.abc();
Console.ReadLine();
}
}
}
It throws an Exception if the the entered number exceeds the available tickets...
You have to use throw to raise an exception :
if( numberOfTickets>numberOfAvailableTickets)
throw new Exception();
The question is telling you to throw an exception if the booked number exceeds the available number.
So you don't need any try or catch in abc (I really hope these names aren't in your real code). You can also remove the if (numberOfTickets < numberOfAvailableTickets) (but keep the code inside.
Above:
pay = 100 * numberOfTickets;
move up:
if( numberOfTickets>numberOfAvailableTickets)
{
Inside the if put:
throw new ArgumentException("numberOfTickets is greater than numberOfAvailableTickets");
You can change ArgumentException to a custom exception if desired
Also note if you're using a catch, it must always be immediately after a try or another catch. You can't have an if between. See the documentation.
In Main, you can either catch that exception, or let it terminate the app (it's not clear from what you provided).
The problem is that you didn't explicitly throw the exception. Unless you do that, the compiler sees nothing wrong with your code, as by default it would only throw exceptions which actually affect the running state of your program.
Although this is a 'quick fix' so to say, just adding a throw new Exception(); where you want the exception to be thrown will work.
However, ideally, I would recommend creating a custom Exception class for this purpose. But the previous line should work anyway :)
I would suggest you to remove the try & catch and simple use MessageBox.
if (numberOfAvaiableTickets < numberOfTickets)
{
MessageBox.Show("Number of tickets exceeded", "ErrorWindow");
}
else
{
pay = 100 * numberOfTickets;
Console.WriteLine("Pay please");
Console.WriteLine(pay);
}