- Introduction
- Understanding Exceptions
- Handling Exceptions
- Creating and Using Custom Exceptions
- Managing Unhandled Exceptions
- Validating User Input
- Apply Your Knowledge
Creating and Using Custom Exceptions
Implement error handling in the user interface.
Create and implement custom error messages.
Create and implement custom error handlers.
Raise and handle errors.
The exception classes provided by the .NET Framework, combined with the custom messages created when you create a new Exception object to throw or rethrow exceptions, should suffice for most of your exception handling requirements. In some cases, however, you might need exception types that are specific to the problem you are solving.
TIP
Using ApplicationException as a Base Class for Custom Exceptions Although you can derive custom exception classes directly from the Exception class, Microsoft recommends that you derive custom exception classes from the ApplicationException class.
The .NET Framework allows you to define custom exception classes. To keep your custom-defined Exception class homogeneous with the .NET exception framework, Microsoft recommends that you consider the following when you design a custom exception class:
-
Create an exception class only if there is no existing exception class that satisfies your requirement.
-
Derive all programmer-defined exception classes from the System.ApplicationException class.
-
End the name of your custom exception class with the word Exception (for example, MyOwnCustomException).
-
Implement three constructors with the signatures shown in the following code:
public class MyOwnCustomException : ApplicationException { // Default constructor public MyOwnCustomException () { } // Constructor accepting a single string message public MyOwnCustomException (string message) : base(message) { } // Constructor accepting a string message and an // inner exception that will be wrapped // by this custom exception class public MyOwnCustomException(string message, Exception inner) : base(message, inner) { } }
Step by Step 3.4 shows you how to create a custom exception.
STEP BY STEP 3.4 - Creating and Using a Custom Exception
Add a new Windows form to the project. Name it StepByStep3_4.
-
Place and arrange controls on the form as shown in Figure 3.6. Name the TextBox control txtDate, the Button control btnIsLeap, and the Label control inside the Results panel lblResult.
Figure 3.6 The leap year finder implements a custom exception for an invalid date format.
-
Switch to the code view and add the following definition for the MyOwnInvalidDateFormatException class to the end of the class definition for project StepByStep3_4:
// You can create your own exception classes by // deriving from the ApplicationException class. // It is good coding practice to end the class name // of the custom exception with the word "Exception" public class MyOwnInvalidDateFormatException : ApplicationException { // It is a good practice to implement the three // recommended common constructors as shown here. public MyOwnInvalidDateFormatException() { } public MyOwnInvalidDateFormatException( string message): base(message) { this.HelpLink = "file://MyOwnInvalidDateFormatExceptionHelp.htm"; } public MyOwnInvalidDateFormatException( string message, Exception inner) : base(message, inner) { }
}
-
Add the following definition for the Date class:
//This class does elementary date handling required //for this program public class Date { private int day, month, year; public Date(string strDate) { if (strDate.Trim().Length == 10) { //Input data might be in an invalid format //In which case, Convert.ToDateTime() // method will fail try { DateTime dt = Convert.ToDateTime(strDate); day = dt.Day; month = dt.Month; year = dt.Year; } //Catch the exception, attach that to the //custom exception and //throw the custom exception catch(Exception e) { throw new MyOwnInvalidDateFormatException( "Custom Exception Says: " + "Invalid Date Format", e); } } else //Throw the custom exception throw new MyOwnInvalidDateFormatException( "The input does not match the " + "required format: MM/DD/YYYY"); } //Find if the given date belongs to a leap year public bool IsLeapYear() { return (year%4==0) && ((year %100 !=0) || (year %400 ==0)); }
}
-
Add the following event handler for the Click event of btnIsLeap:
private void btnIsLeap_Click( object sender, System.EventArgs e) { try { Date dt = new Date(txtDate.Text); if (dt.IsLeapYear()) lblResult.Text = "This date is in a leap year"; else lblResult.Text = "This date is NOT in a leap year"; } //Catch the custom exception and //display an appropriate message catch (MyOwnInvalidDateFormatException dte) { string msg; //If some other exception was also //attached with this exception if (dte.InnerException != null) msg = String.Format( "Message:\n {0}\n\n Inner Exception:\n {1}", dte.Message, dte.InnerException.Message); else msg = String.Format( "Message:\n {0}\n\n Help Link:\n {1}", dte.Message, dte.HelpLink); MessageBox.Show(msg, dte.GetType().ToString()); }
}
-
Insert a Main() method to launch the form. Set the form as the startup object for the project.
-
Run the project. Enter a date and click the button. If the date you enter is in the required format, you see a result displayed in the Results group box; otherwise, you get a message box showing the custom error message thrown by the custom exception, as in Figure 3.7.
Figure 3.7 You can associate a customized error message and a help link with a custom exception.
Guided Practice Exercise 3.1
You are a Windows developer for a data analysis company. For one of your applications you need to create a keyword searching form that asks for a filename and a keyword from the user (as shown in Figure 3.8). The form should search for the keyword in the file and display the number of lines that contain the keyword in the results group box. Your form assumes that the entered keyword is a single word. If it is not a single word, you need to create and throw a custom exception for that case.
Figure 3.8 The keyword searching form throws a custom exception if the input is not in the required format.
How would you throw a custom exception to implement custom error messages and custom error handling in your program?
You should try working through this problem on your own first. If you get stuck, or if you'd like to see one possible solution, follow these steps:
-
Add a new form to your Visual C# .NET project. Name the form GuidedPracticeExercise3_1.cs.
-
Place and arrange controls on the form as shown in Figure 3.8. Name the TextBox control for accepting the filename txtFileName and the Browse control btnBrowse. Set the ReadOnly property of txtFileName to true. Name the TextBox control for accepting the keyword txtKeyword and the Button control btnSearch. Set the tab order of the form in the correct order, to ensure that the user's cursor is not placed in the read-only text box when the application starts.
-
Add an OpenFileDialog control to the form and change its name to dlgOpenFile.
-
Create a new class named BadKeywordFormatException that derives from ApplicationException and place the following code in it:
public class BadKeywordFormatException : ApplicationException { public BadKeywordFormatException() { } public BadKeywordFormatException(string message): base(message) { } public BadKeywordFormatException(string message, Exception inner): base(message, inner) { } }
-
Create a method named GetKeywordFrequency() in the GuidedPracticeExercise3_1 class. This method should accept a string and return the number of lines that contain the string. Add the following code to the method:
private int GetKeywordFrequency(string path) { if(this.txtKeyword.Text.Trim().IndexOf(' ') >= 0) throw new BadKeywordFormatException( "The keyword must only have a single word"); int count = 0; if (File.Exists(path)) { StreamReader sr = new StreamReader(txtFileName.Text); while (sr.Peek() > -1) if (sr.ReadLine().IndexOf(txtKeyword.Text) >= 0) count++; } return count; }
-
Add the following code to the Click event handler of btnBrowse:
private void btnBrowse_Click( object sender, System.EventArgs e) { if (dlgOpenFile.ShowDialog() == DialogResult.OK) txtFileName.Text = dlgOpenFile.FileName; }
-
Add the following code to the Click event handler of btnSearch:
private void btnSearch_Click( object sender, System.EventArgs e) { if (txtKeyword.Text.Trim().Length == 0) { MessageBox.Show( "Please enter a keyword to search for", "Missing Keyword"); return; } try { lblResult.Text = String.Format( "The keyword: '{0}', was found in {1} lines", txtKeyword.Text, GetKeywordFrequency(txtFileName.Text)); } catch(BadKeywordFormatException bkfe) { string msg = String.Format( "Message:\n {0}\n\n StackTrace:\n{1}", bkfe.Message, bkfe.StackTrace); MessageBox.Show(msg, bkfe.GetType().ToString()); } }
-
Insert the Main() method to launch the form GuidedPracticeExercise3_1.cs. Set the form as the startup object for the project.
-
Run the project. Click the Browse button and select an existing file. Enter the keyword to search for in the file and click the Search button. If the keyword entered is in the wrong format (for example, if it contains two words), the custom exception is raised.
If you have difficulty following this exercise, review the sections "Handling Exceptions" and "Creating and Using Custom Exceptions" earlier in this chapter. After reviewing, try this exercise again.