Protect Life Save Forests Protect Life Save Forests - 19 days ago 5
C# Question

Inner Exceptions C#

Story: I've 3 functions from 3 different classes. Functions calling order is:

Form1_Load(...)
->
Student.GetAllStudents(...)
->
StudentDAL.GetStudentInformation(...)
->
ConnectionManager.GetConnection(...)


What I want to do is to display StackTrace of the inner most function i.e.
ConnectionManager.GetConnection()
, in a
MessageBox
in Form1 class. In other words I don't want to use
MessageBox
in any inner classes, but only in outer most class that is Form1 class.

Problem: To get inner exceptions we can use
InnerException
or
GetBaseException()
etc. but when I try to get inner exception it throws an exception "Object reference not set to an instance", meaning that there is no inner exception and, when I check, the value is also
null
. All I want to know here why it's
null
? Shouldn't it be holding reference to the inner exception? Correct me if I'm wrong.

Function codes :


  1. Form1_Load(...)


    private void Form1_Load(object sender, EventArgs e)
    {
    try
    {
    DataTable dt = new DataTable();
    dt.Load((**new Student().GetAllStudents()**));
    if (dt.Rows.Count <= 0)
    {
    MessageBox.Show("Student table empty.");
    }
    else
    {
    this.dataGridView1.DataSource = dt;
    }
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message+Environment.NewLine+"Source(s) : "+ex.StackTrace.Substring(0, ex.StackTrace.LastIndexOf("at")));
    }

  2. GetAllStudents(...)


    public SqlDataReader GetAllStudents()
    {
    try
    {
    return StudentInformationDataAccessLayer.GetStudentInformation();
    }
    catch (Exception ex)
    {
    throw ex;
    }
    }

  3. GetStudentInformation(...)


    public static SqlDataReader GetStudentInformation()
    {
    try
    {
    SqlConnection sqlCon = null;
    sqlCon = ConnectionManager.GetConnection();
    if (sqlCon == null)
    {
    return null;
    }
    String Query = null;
    Query = "SELECT * FROM [dbo].[Student]";
    SqlCommand cmd = new SqlCommand(Query, sqlCon);
    SqlDataReader dr = null;
    dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
    return dr;
    }
    catch (Exception ex)
    {
    throw ex;
    }
    }

  4. GetConnection(...)


    public static SqlConnection GetConnection()
    {
    String _connectionString = null;
    _connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;

    if (_connectionString == null)
    {
    return null;
    }

    try
    {
    SqlConnection connection = new SqlConnection(_connectionString);
    connection.Open();
    return connection;
    }
    catch (Exception ex)
    {
    throw ex;
    }
    }


Answer

If you want to re-throw with inner exception set, use below code, but remember that you will lose stack trace:

try
{
   ...
}
catch (Exception ex)
{
  throw new Exception("message", ex);
}

To just re-throw an exception and preserve stack trace, use:

try
{
   ...
}
catch (Exception ex)
{
  throw;
}