Introduction to Techniques of Dealing with Exceptions
Introduction to Techniques of Dealing with Exceptions
Throwing an Exception
Introduction
As mentioned previously, the Exception class is equipped with a Message property that carries a message for the error that occurred. We also mentioned that the message of this property may not be particularly useful to a user. Fortunately, you can create your own message and pass it to an Exception object. To be able to receive custom messages, the Exception class provides the following constructor:
public Exception(string message);
As mentioned already, all exceptions classes derive directly or indirectly from Exception. As a result, all thoses classes are equipped with a default constructor and all of them inherit the constructor that takes a string as argument.
To use the constructor that uses a string parameter, in the section in which you are anticipating the error, type the throw keyword followed by a new instance of the Exception class using this constructor. Here is an example:
@{
ViewBag.Title = "Calculations";
}
<h2>Calculations</h2>
@{
string message = "";
double result = 0.00;
string oper = "";
double number1 = 0.00, number2 = 0.00;
if (IsPost)
{
try
{
number1 = double.Parse(Request["txtNumber1"]);
number2 = double.Parse(Request["txtNumber2"]);
oper = Request["txtNumber2"];
if( (oper != "+") && (oper != "-") && (oper != "*") && (oper != "/") )
{
throw new Exception(oper);
}
switch (oper)
{
case "+":
result = number1 + number2;
break;
case "-":
result = number1 - number2;
break;
case "*":
result = number1 * number2;
break;
case "/":
result = number1 / number2;
break;
default:
message = "Bad Operation";
break;
}
}
catch (Exception exc)
{
message = "The value you entered is not a valid number.";
}
}
}
@using (Html.BeginForm())
{
<table>
<tr>
<td>Number 1:</td>
<td>@Html.TextBox("txtNumber1", @number1)</td>
</tr>
<tr>
<td>Operator:</td>
<td>@Html.TextBox("txtOperator", @oper)</td>
</tr>
<tr>
<td>Number 2:</td>
<td>@Html.TextBox("txtNumber2", @number1)</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" name="btnCalculate" value="Calculate" /></td>
</tr>
<tr>
<td>Result:</td>
<td>@Html.TextBox("txtResult", @result)</td>
</tr>
</table>
<p>@message</p>
}
Practical Learning: Throwing an Exception
Control | (Name) | Text | Other Properties |
Label | Number 1 | ||
Label | Operation | ||
Label | Number 2 | ||
Label | Result | ||
Label | Operation | ||
TextBox | txtNumber1 | ||
ComboBox | cbxOperators | Items:
+ - * / |
|
TextBox | txtNumber2 | ||
Button | btnCalculate | Calculate | |
TextBox | txtResult |
using System;
using System.Windows.Forms;
namespace Algebra1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
double result = 0.00;
double number1 = double.Parse(txtNumber1.Text);
double number2 = double.Parse(txtNumber2.Text);
string oper = cbxOperators.Text;
if ((oper != "+") && (oper != "-") && (oper != "*") && (oper != "/"))
{
throw new Exception(oper);
}
switch (oper)
{
case "+":
result = number1 + number2;
break;
case "-":
result = number1 - number2;
break;
case "*":
result = number1 * number2;
break;
case "/":
result = number1 / number2;
break;
default:
MessageBox.Show("Bad Operation", "Elementary Algebra");
break;
}
txtResult.Text = result.ToString();
}
catch (Exception)
{
MessageBox.Show("The value you entered is not a valid number.",
"Elementary Algebra");
}
}
}
}
Control | (Name) | Text | TextAlign |
Label | Organization for Fundraising Events | ||
Label | __________________________________ | ||
Label | Two-Way Campaign Distribution | ||
Label | Amount to Allocate: | ||
TextBox | txtAllocation | ||
Label | In the Ratio: | ||
TextBox | txtPortion1 | Center | |
Label | : | ||
TextBox | txtPortion2 | Center | |
Button | btnCalculate | Calculate | |
Label | __________________________________ | ||
Label | Part 1 Receives: | ||
TextBox | txtPart1 | ||
Label | Part 2 Receives: | ||
TextBox | txtPart2 |
using System; using System.Windows.Forms; namespace PledgeDistribution2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } (int, int) DistributeParts(int amount, int portion1, int portion2) { int totalRatios = portion1 + portion2; int eachPart = amount / totalRatios; int result = eachPart * portion1; return (result, amount - result); } private void btnCalculate_Click(object sender, EventArgs e) { try { int amtPledged = int.Parse(txtAllocation.Text); int ratio1 = int.Parse(txtPortion1.Text); int ratio2 = int.Parse(txtPortion2.Text); (int first, int second) portions = DistributeParts(amtPledged, ratio1, ratio2); txtPart1.Text = portions.first.ToString(); txtPart2.Text = portions.second.ToString(); } catch (FormatException) { MessageBox.Show("The value you entered for the amount to allocate " + "or pledge is not valid. Only natural numbers " + "(such as 200, 1250, 5000, or 100000) are allowed.", "Organization for Fundraising Events"); } } } }
Amount to Allocate: 8500 In the Ratio: 4:3
Exceptions and Methods
There are various ways you can involve exceptions in a function or method. When it comes to functions and methods, one way you can use the throw option is to get out of the function or method at any time, for any reason. Consider the following code:
using System;
class Exercise
{
public void ShowMessage()
{
throw new Exception();
MessageBox.Show("This is the wonderful world of C# programming.");
}
}
In this example, the line that holds the message box will never be reached. One way you can proceed in a function or method is to throw an exception if something happens. That is, you can create a conditional statement that would consider, or throw an exception.
Practical Learning: Throwing an Exception from a Method
using System;
using System.Windows.Forms;
namespace PledgeDistribution2
{
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
(int, int) DistributeParts(int amount, int portion1, int portion2)
{
int totalRatios = portion1 + portion2;
if (totalRatios == 0)
throw new FormatException("The value provided for one or both ratios is not valid.");
int eachPart = amount / totalRatios;
int result = eachPart * portion1;
return (result, amount - result);
}
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
int amtPledged = int.Parse(txtAllocation.Text);
int ratio1 = int.Parse(txtPortion1.Text);
int ratio2 = int.Parse(txtPortion2.Text);
(int first, int second) portions = DistributeParts(amtPledged, ratio1, ratio2);
txtPart1.Text = portions.first.ToString();
txtPart2.Text = portions.second.ToString();
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the amount to allocate " +
"or pledge is not valid. Only natural numbers " +
"(such as 200, 1250, 5000, or 100000) are allowed.",
"Organization for Fundraising Events");
}
}
}
}
Amount to Allocate: 8500 In the Ratio: 0:0
using System; using System.Windows.Forms; namespace PledgeDistribution2 { public partial class Form1 : Form { public Form1() => InitializeComponent(); int DistributeFirstPart(int amount, int portion1, int portion2) { if (portion1 != 0) { int totalRatios = portion1 + portion2; int eachPart = amount / totalRatios; int result = eachPart * portion1; return result; } else throw new FormatException("The value provided for the first ratio portion is not valid."); } int Subtract(int first, int second) { if (first == 0) throw new FormatException("The value provided for the amount to pledge must be a positive number."); return first - second; } private void btnCalculate_Click(object sender, EventArgs e) { try { int amtPledged = int.Parse(txtAllocation.Text); int ratio1 = int.Parse(txtPortion1.Text); int ratio2 = int.Parse(txtPortion2.Text); int part1 = DistributeFirstPart(amtPledged, ratio1, ratio2); int part2 = Subtract(amtPledged, part1); txtPart1.Text = part1.ToString(); txtPart2.Text = part2.ToString(); } catch (FormatException) { MessageBox.Show("The value you entered for the amount to allocate " + "or pledge is not valid. Only natural numbers " + "(such as 200, 1250, 5000, or 100000) are allowed.", "Organization for Fundraising Events"); } } } }
Exceptions and Properties
If you create a non-automatic property that processes some data and returns a valid result, if there is a possibility that something could go wrong in the calculation, you can make the property throw an exception. You can perform some procesing in the set clause of the property. In that clause, you can throw an exception. Here is an example:
using System;
public class WorkDay
{
private double tw;
public WorkDay(double time)
{
tw = time;
}
public double TimeWorked
{
get
{
return tw;
}
set
{
if (tw > 24)
throw new FormatException("Nobody can work more than 24 hours in one day.");
tw = value;
}
}
}
Or you can handle the exception in the get clause.
Topics on Handling Exceptions
Catching Various Exceptions
In the above examples, when we anticipated some type of problem, we instructed the compiler to use our default catch section. We left it up to the compiler to find out when there was a problem and we provided a catch section to deal with it. A secttion of code with numerous or complex operations and requests can also produce different types of errors. You should be able to face different problems and deal with them individually, each by its own kind. To do this, you can create different catch sections, each made for a particular error. The formula to follow is:
try { // Code to Try } catch(Arg1) { // One Exception } catch(Arg2) { // Another Exception }
The compiler would proceed from top-down:
Multiple catch clauses are written if or when a try block is expected to throw different types of errors. For example, in our calculator, we want to consider only the addition, the subtraction, the multiplication, and the division. It is also likely that the user may type one or two invalid numbers. This leads us to know that our project can produce at least two types of errors. Based on this, we can address them using two catch clauses.
Obviously various bad things could happen when a form is used. Imagine that the user wants to perform a division. You need to tell the webpage what to do if the user enters the denominator as 0 (or 0.00). If this happens, one of the options you should consider is to display a message and get out. Fortunately, the .NET Framework provides the DivideByZeroException class to which we were introduced in the previous lesson to deal with an exception caused by division by zero. As done with the message passed to the Exception class, you can compose your own message and pass it to the DivideByZeroException(string message) constructor.
Practical Learning: Throwing Various Exceptions
using System;
using System.Windows.Forms;
namespace Algebra1
{
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
double result = 0.00;
double number1 = double.Parse(txtNumber1.Text);
double number2 = double.Parse(txtNumber2.Text);
string oper = cbxOperators.Text;
if ((oper != "+") && (oper != "-") && (oper != "*") && (oper != "/"))
{
throw new Exception(oper);
}
switch (oper)
{
case "+":
result = number1 + number2;
break;
case "-":
result = number1 - number2;
break;
case "*":
result = number1 * number2;
break;
case "/":
result = number1 / number2;
break;
default:
MessageBox.Show("Bad Operation", "Elementary Algebra");
break;
}
txtResult.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("You type an invalid number. Please correct it",
"Elementary Algebra");
}
catch (Exception ex)
{
MessageBox.Show("Operation Error: " + ex.Message + " is not a valid operator",
"Elementary Algebra");
}
}
}
}
Exception Filters
Sometimes you will have different controls that may throw the same type of exception. The problem is that these controls may present the same error message. For example, if you have more than two text boxes that expect numeric values, if a valid value is not provided, each of the controls would throw a FormatException exception. The problem is that when one of those controls throws the exception, you may need a way to either know what control threw the exception or what exception was thrown.
Filtering an exception consists of specifying a criterion by which a particular exception, among others, would be selected. The C# language provides a mechanism that allows you to get more details about an exception. To start, you must use a technique that would be applied to each particular error. One way to do this is to use the throw keyword to create a custom message when an exception is thrown. To help you select an exception, the C# language provides the when keyword. The formula to use it is:
try
{
. . .
}
catch(exception-parameter) when (condition)
{
. . .
}
In the catch clause, pass an exception-parameter as we have done so far. This is followed by the when keyword that is used as in an if() conditional statement. In its parentheses, provide a logical expression that can evaluate to true or false. If that expression is true, the body of the catch clause would execute.
Nesting an Exception
You can create an exception inside of another. This is referred to as nesting an exception. This is done by applying the same techniques we used to nest conditional statements. This means that you can write an exception that depends on, and is subject to, another exception. To nest an exception, write a try block in the body of the parent exception. The nested try block must be followed by its own catch clause(s). To effectively handle the exception(s), make sure you include an appropriate throw in the try block.
Practical Learning: Nesting an Exception
using System; using System.Windows.Forms; namespace Algebra1 { public partial class Form1 : Form { public Form1() => InitializeComponent(); private void btnCalculate_Click(object sender, EventArgs e) { try { double result = 0.00; double number1 = double.Parse(txtNumber1.Text); double number2 = double.Parse(txtNumber2.Text); if ((cbxOperators.Text != "+") && (cbxOperators.Text != "-") && (cbxOperators.Text != "*") && (cbxOperators.Text != "/")) throw new Exception(cbxOperators.Text); switch (cbxOperators.Text) { case "+": result = number1 + number2; break; case "-": result = number1 - number2; break; case "*": result = number1 * number2; break; case "/": try { if (number2 == 0) throw new DivideByZeroException("Division by zero is not allowed"); result = number1 / number2; } catch (DivideByZeroException ex) { MessageBox.Show(ex.Message, "Elementary Algebra"); } break; default: MessageBox.Show("Bad Operation", "Elementary Algebra"); break; } txtResult.Text = result.ToString(); } catch (FormatException) { MessageBox.Show("You type an invalid number. Please correct it", "Elementary Algebra"); } catch (Exception ex) { MessageBox.Show("Operation Error: " + ex.Message + " is not a valid operator", "Elementary Algebra"); } } } }
|
||
Previous | Copyright © 2001-2021, FunctionX | Next |
|