Exception/Error Handling in ASP.Net Simplified

Guys, this is not the first time when something is written for exceptions and error handling in the web. There are enormous articles written earlier for this topic. I have tried writing this article for beginners explaining these concepts in simple language and step-by-step.

This is a very basic article for beginners that show exception handling and error handling techniques in ASP.NET.

Where there are codes, the chances for exceptions/error always exist so it is very important for developers when developing web applications to understand the errors and implement the error handling techniques to avoid breaking pages or providing unhandled errors to end uses.

What Exceptions are

Guys, the MSDN says that an exception is an error condition or unexpected behavior encountered by an executing program. Exceptions can be raised because of a fault in your code or in code that you call (such as a shared library), unavailable operating system resources or unexpected conditions the Common Language Runtime encounters (such as code that cannot be verified).

Get practical knowledge on Exceptions at Dot Net Online Training

Exceptions are nothing but an unseen error occurs when executing code logic.
Demo Web Application

I have created a web application as an example to understand the exception handling.

Sample Code

  1. namespace ErrorHandlingDemo
  2. {
  3. public partial class _Default : Page
  4. {
  5. protected void Page_Load(object sender, EventArgs e)
  6. {
  7. if (!IsPostBack)
  8. {
  9. string connectionString = ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString;
  10. string selectSQL = "SELECT * FROM tblEmployees";
  11. SqlConnection con = new SqlConnection(connectionString);
  12. SqlCommand cmd = new SqlCommand(selectSQL, con);
  13. SqlDataAdapter adapter = new SqlDataAdapter(cmd);
  14. DataSet ds = new DataSet();
  15. adapter.Fill(ds, "Employees");
  16. GridView1.DataSource = ds;
  17. GridView1.DataBind();
  18. }
  19. }
  20. }
  21. }

Using this web page I am trying to display employee's details in a grid view control on page load. The following is the output page with employee details.

Example to show data on the webpage from the database using some ADO.NET code:

Now from this basic what if the table containing employees is deleted or renamed or the developer has used the wrong table name in the code behind.

I have now changed the table name in the code and complied and run the page.

  1. string selectSQL = "SELECT * FROM tblEmployees1";

After running the application a broken Yellow screen is shown with the message Invalid Object name



But exposing this error message in Yellow page format is a bad practice because:

  • It does not make any sense to the end user although it can be helpful for developers for debugging and investigating the issue.
  • This exposure can help hackers to get information about your application that is not good according to security.

Handling Exceptions

Using Try catch finally Block

Using a try catch finally block, exceptions can be handled.

Whenever an exception happens when executing the logic in a try block, the control is immediately moved to the catch block that reads the exception message and after catching the exception in the catch block a user-friendly error can be shown to the end users.

Sample Code

  1. namespace ErrorHandlingDemo
  2. {
  3. public partial class _Default : Page
  4. {
  5. protected void Page_Load(object sender, EventArgs e)
  6. {
  7. if (!IsPostBack)
  8. {
  9. try
  10. {
  11. string connectionString = ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString;
  12. string selectSQL = "SELECT * FROM tblEmployees1";
  13. SqlConnection con = new SqlConnection(connectionString);
  14. SqlCommand cmd = new SqlCommand(selectSQL, con);
  15. SqlDataAdapter adapter = new SqlDataAdapter(cmd);
  16. DataSet ds = new DataSet();
  17. adapter.Fill(ds, "Employees");
  18. GridView1.DataSource = ds;
  19. GridView1.DataBind();
  20. }
  21. catch (Exception ex)
  22. {
  23. // Log the exception
  24. Label1.Text = "Something Bad happened, Please contact Administrator!!!!";
  25. }
  26. finally
  27. {
  28. }
  29. }
  30. }
  31. }
  32. }


Apart from the try catch exception handling technique, the ASP.NET Framework has error handling events where exceptions can be caught.

When there is an unhandled error at the code level, meaning if the code does not have a structured try catch block to handle exceptions, then that can be handled at the page level.

An unhandled exception is being propagated to the page level if not handled at the code level.

At the page level Page_Error is the event that catches the exception and we can handle the exception at the page level.

If an exception is not handled at the page level then it will be propagated to the application level and at the application level in the global.aspx file there is an application_Error event where the exception can be handled.

Get practical knowledge on it from live experts at Dot Net Training

It could be a centralized place to handle all the required exception handling at the project level.

  • Page level error event

    protected
    void Page_Error(object sender, EventArgs e)
    {
    Exception Ex = Server.GetLastError();
    Server.ClearError();
    Response.Redirect("Error.aspx");
    }
  • Application level error event

    void
     Application_Error(object sender, EventArgs e)
    {
    // Code that runs when an unhandled error occurs
    Exception Ex =Server.GetLastError();
    Server.ClearError();
    Server.Transfer("Error.aspx");
    }

Exception Propagation at ASP.NET web application



Custom Error in ASP.NET

An exception in the application can be handled using the custom error pages.

Custom error pages can be displayed instead of a Yellow broken page as per the exception if it is not handled at any lower level.

Custom error pages are displayed depending on the ASP.NET HTTP status codes.

It can be defined at two levels.

  1. Application level: In the web.Config File

    In the Webconfig file at the application root level we need to set the CustomErrors element “On” and error with statusCode and Redirect.

    <customErrors mode="On" defaultRedirect="DefaultError.aspx">
    <error statusCode="404" redirect="PageNotFound.aspx"/>
    <error statusCode="500" redirect="ServerError.aspx"/>
    </customErrors>

    A Custom Errors Element has the following three modes available:
    Off: Custom Error pages are not displayed.
    On: Custom Error page are displayed on both local and remote machines
    Remote Only: Custom Error pages are displayed on the remote machine and an exception on
    the local machine
  1. Page Level: At Page directive

    We can set the custome error page at the page level using as below:

    ErrorPage="~/ServerError.aspx"

It will work especially for this page only.

Note

If Pagelevel custom error, the application level custom error and redirection from application_error from global.aspx are present then the page level has the highest priority then application_error and then application level custom in web Config file.

Exception Logging In ASP.NET

  • Logging to Event Viewer
  • Logging to Database Table
  • Logging to Text file

Logging to Event Viewer

The Wiki says the Event Viewer is nothing but an Event Viewer, a component of Microsoft's Windows NT line of operating systems. It lets administrators and users view the event logs on a local or remote machine.

Go to Run -> Type EentVwr.

Event Log Types

  1. Application Log
  2. Security Log
  3. System Log

In the Application and Service Logs, I have created a Custom Event Log with the following details using the code.

  1. EventLog.CreateEventSource("AbhiTesting", "TestLog");

Log Name: Test Log
Source: AbhiTesting

You can modify the Name and source depending on your requirements and provide some dynamic way to create it I have hardcoded the values.



Sample Code

  1. public static void LogErrorToEventViewer(Exception ex)
  2. {
  3. StringBuilder sb = new StringBuilder();
  4. sb.Append("********************" + " Error Log - " + DateTime.Now + "*********************");
  5. sb.Append(Environment.NewLine);
  6. sb.Append(Environment.NewLine);
  7. sb.Append("Exception Type : " + ex.GetType().Name);
  8. sb.Append(Environment.NewLine);
  9. sb.Append("Error Message : " + ex.Message);
  10. sb.Append(Environment.NewLine);
  11. sb.Append("Error Source : " + ex.Source);
  12. sb.Append(Environment.NewLine);
  13. if (ex.StackTrace != null)
  14. {
  15. sb.Append("Error Trace : " + ex.StackTrace);
  16. }
  17. Exception innerEx = ex.InnerException;
  18. while (innerEx != null)
  19. {
  20. sb.Append(Environment.NewLine);
  21. sb.Append(Environment.NewLine);
  22. sb.Append("Exception Type : " + innerEx.GetType().Name);
  23. sb.Append(Environment.NewLine);
  24. sb.Append("Error Message : " + innerEx.Message);
  25. sb.Append(Environment.NewLine);
  26. sb.Append("Error Source : " + innerEx.Source);
  27. sb.Append(Environment.NewLine);
  28. if (ex.StackTrace != null)
  29. {
  30. sb.Append("Error Trace : " + innerEx.StackTrace);
  31. }
  32. innerEx = innerEx.InnerException;
  33. }
  34. if(EventLog.SourceExists("AbhiTesting"))
  35. {
  36. EventLog eventlog=new EventLog("TestLog");
  37. eventlog.Source = "AbhiTesting";
  38. eventlog.WriteEntry(sb.ToString(), EventLogEntryType.Error);
  39. }
  40. }

EventLogentry has options to write the error as various entry types.

The Windows Event Log can be used to store the error logs for developers to see the error messages and provide solutions to the issues.

Know more information from live experts at Dot Net Online Course

Logging to Database Table

An exception can be written to a database table for the developer to get the log and investigate the error to provide a solution for it.

Table Script

  1. CREATE TABLE [dbo].[tblExceptionLog]
  2. (
  3. [ID] [int] IDENTITY(1,1) NOT NULL,
  4. [ExceptionMesage] [nvarchar](max) NULL,
  5. [LogDate] [datetime] NULL,
  6. [Source] [varchar](50) NULL,
  7. [Trace] [varchar](max) NULL,
  8. CONSTRAINT [PK_tblExceptionLog] PRIMARY KEY CLUSTERED
  9. (
  10. [ID] ASC
  11. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS =      ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  12. ) ON [PRIMARY]

Stored Procedure

  1. Create PROCEDURE Sp_LogException
  2. (
  3. @ExceptionMessage nvarchar(max),
  4. @Source Varchar(50)
  5. )
  6. AS
  7. BEGIN
  8. SET NOCOUNT ON;
  9. INSERT INTO [School].[dbo].[tblExceptionLog]
  10. ([ExceptionMesage]
  11. ,[LogDate]
  12. ,[Source]
  13. ,[Trace])
  14. VALUES
  15. (@ExceptionMessage,GETDATE(),@Source,null)
  16. END

Sample Code

  1. public static void LogErrorToDB(Exception ex)
  2. {
  3. StringBuilder sb = new StringBuilder();
  4. sb.Append("********************" + " Error Log - " + DateTime.Now + "*********************");
  5. sb.Append(Environment.NewLine);
  6. sb.Append(Environment.NewLine);
  7. sb.Append("Exception Type : " + ex.GetType().Name);
  8. sb.Append(Environment.NewLine);
  9. sb.Append("Error Message : " + ex.Message);
  10. sb.Append(Environment.NewLine);
  11. sb.Append("Error Source : " + ex.Source);
  12. sb.Append(Environment.NewLine);
  13. if (ex.StackTrace != null)
  14. {
  15. sb.Append("Error Trace : " + ex.StackTrace);
  16. }
  17. Exception innerEx = ex.InnerException;
  18. while (innerEx != null)
  19. {
  20. sb.Append(Environment.NewLine);
  21. sb.Append(Environment.NewLine);
  22. sb.Append("Exception Type : " + innerEx.GetType().Name);
  23. sb.Append(Environment.NewLine);
  24. sb.Append("Error Message : " + innerEx.Message);
  25. sb.Append(Environment.NewLine);
  26. sb.Append("Error Source : " + innerEx.Source);
  27. sb.Append(Environment.NewLine);
  28. if (ex.StackTrace != null)
  29. {
  30. sb.Append("Error Trace : " + innerEx.StackTrace);
  31. }
  32. innerEx = innerEx.InnerException;
  33. }
  34. String Connection = ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString;
  35. SqlConnection conn = new SqlConnection(Connection);
  36. SqlCommand cmd = new SqlCommand("Sp_LogException", conn);
  37. cmd.CommandType = CommandType.StoredProcedure;
  38. SqlParameter param = new SqlParameter();
  39. cmd.Parameters.Add("@ExceptionMessage", SqlDbType.NVarChar).Value = sb.ToString();
  40. cmd.Parameters.Add("@Source", SqlDbType.VarChar).Value ="Your Appliaction Name";
  41. conn.Open();
  42. cmd.ExecuteNonQuery();
  43. conn.Close();
  44. }

Global.aspx Error Event

  1. Application_Error(object sender, EventArgs e)
  2. {
  3. // Code that runs when an unhandled error occurs
  4. Exception Ex = Server.GetLastError();
  5. Server.ClearError();
  6. // ExceptionLogging.LogErrorToEventViewer(Ex);
  7. ExceptionLogging.LogErrorToDB(Ex);
  8. Server.Transfer("Error.aspx");
  9. }

Data Stored in DB



Logging to Text file

An exception can be logged to a text file also according to the application requirements and company policy. I have provided the example to a written log to a text file at root directory of the application. You can modify the code and store to a server or to a folder for the error log for debugging and investigating the issues.

Sample Code:

  1. public static void LogErrorToText(Exception ex)
  2. {
  3. StringBuilder sb = new StringBuilder();
  4. sb.Append("********************" + " Error Log - " + DateTime.Now + "*********************");
  5. sb.Append(Environment.NewLine);
  6. sb.Append(Environment.NewLine);
  7. sb.Append("Exception Type : " + ex.GetType().Name);
  8. sb.Append(Environment.NewLine);
  9. sb.Append("Error Message : " + ex.Message);
  10. sb.Append(Environment.NewLine);
  11. sb.Append("Error Source : " + ex.Source);
  12. sb.Append(Environment.NewLine);
  13. if (ex.StackTrace != null)
  14. {
  15. sb.Append("Error Trace : " + ex.StackTrace);
  16. }
  17. Exception innerEx = ex.InnerException;
  18. while (innerEx != null)
  19. {
  20. sb.Append(Environment.NewLine);
  21. sb.Append(Environment.NewLine);
  22. sb.Append("Exception Type : " + innerEx.GetType().Name);
  23. sb.Append(Environment.NewLine);
  24. sb.Append("Error Message : " + innerEx.Message);
  25. sb.Append(Environment.NewLine);
  26. sb.Append("Error Source : " + innerEx.Source);
  27. sb.Append(Environment.NewLine);
  28. if (ex.StackTrace != null)
  29. {
  30. sb.Append("Error Trace : " + innerEx.StackTrace);
  31. }
  32. innerEx = innerEx.InnerException;
  33. }
  34. string filePath = HttpContext.Current.Server.MapPath("ErrorLog.txt");
  35. if (File.Exists(filePath))
  36. {
  37. StreamWriter writer = new StreamWriter(filePath, true);
  38. writer.WriteLine(sb.ToString());
  39. writer.Flush();
  40. writer.Close();
  41. }
  42. }

Conclusion

Guys we have seen in the preceding about the exceptions happening at the application level and various levels and determine how and where to handle and log the errors.

Exceptions/Errors in an ASP.NET web application propagates from code to the page to the application level.

You can handle and use the error handling techniques according to the project and company policy. It is very important to understand the requirements and uses of available techniques for better performance and error handling.

Get more information with practical examples at .net online training