SqlException not caught in Winforms - c#

I got this code:
try
{
using (SqlConnection sourceCnx = new SqlConnection(SOURCE_CONN_STRING))
{
sourceCnx.Open();
SqlCommand sysCmd = sourceCnx.CreateCommand();
sysCmd.CommandText = "My query";
sysCmd.ExecuteNonQuery();
}
}
catch (Exception)
{
//Throwing a message box informing that there is an error
}
I want to display a message when the user is no longer connected to the internet.
But when I debug my program without an internet connection, the program crashes with a SqlException. (The "catch" block does not catch the exception)
I tried to add catch (SqlException) { // code } before catch (Exception) but it doesn't work.
I still have an exception instead of a message displayed by the catch block.
I don't know what to do because if I create a method to test the internet connection (try to ping google.com) then return true if it's ok, it will be the same : I got an exception because of no internet connection.
Any idea?

You have set your environment to always break when a CLR exception is thrown. You can leave it like that if you wish and press F5 to carry on execution of your program. Or you can turn this off (it is switched off by default):
Go to Debug menu, select Exceptions and ensure Common Language Runtime Exceptions is not checked.

You might want to put the exception handing inside the using block, like this:
using (SqlConnection sourceCnx = new SqlConnection(SOURCE_CONN_STRING))
{
try
{
sourceCnx.Open();
SqlCommand sysCmd = sourceCnx.CreateCommand();
sysCmd.CommandText = "My query";
sysCmd.ExecuteNonQuery();
}
catch (SqlException e)
{
// This will catch any SQL Exceptions.
// Use "throw;" if you want to rethrow the exception up the stack
}
catch (Exception e)
{
// This will catch any other exceptions.
// Use "throw;" if you want to rethrow the exception up the stack
}
}
Assuming that you have actually replaced "My Query" with something specific to your scenario, the SqlException is most likely down to your machine not being able to see the SQL Server instance. Try pinging it...

Try with this:
try
{
using (SqlConnection sourceCnx = new SqlConnection(SOURCE_CONN_STRING))
{
sourceCnx.Open();
SqlCommand sysCmd = sourceCnx.CreateCommand();
sysCmd.CommandText = "My query";
sysCmd.ExecuteNonQuery();
}
}
catch(SqlException sqlEx)
{
MessageBox.Show("there was a sql issue");
}
catch(Exception ex)
{
MessageBox.Show("there was some other issue");
}

In the part of the catch code, you have to set a variable not? And after that take any of her property.
For example:
try
{
using (SqlConnection sourceCnx = new SqlConnection(SOURCE_CONN_STRING))
{
sourceCnx.Open();
SqlCommand sysCmd = sourceCnx.CreateCommand();
sysCmd.CommandText = "My query";
sysCmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
//example
MessageBox.show(ex.message);
}

I think you should get the BaseException
catch (Exception exp)
{
if (exp.GetBaseException() is System.Data.SqlClient.SqlException)
{
var sqlException = exp.GetBaseException() as System.Data.SqlClient.SqlException;
if (sqlException != null && sqlException.Number == 547)
{
//do something
}
}
//do something
}

Related

How to return exception message with success value in C# windows application?

I am trying to return a success or failure value from one class to another. In case of failure, I also need to return the error message to the other class. How can this be achieved with a function returning integer?
clsDAL.cs
public int Insert(string name, string address)
{
try
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_demo";
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#id",1);
cmd.Parameters.AddWithValue("#name",name);
int i = cmd.ExecuteNonQuery();
return i;
}//try
catch(Exception e)
{
return -1; // Incase of failure need to return Exception error
}
}
clsBLL.cs
public int InsertData(string name, string address)
{
int i = dobj.InsertTable(name, address);
if (i == 1)
{
MessageBox.Show("Record Inserted successfully");
}
else
{
MessageBox.Show("Insertion failed"); // Show the exception message here
}
}
Move the try-catch blocks to the parent method so that you have the actual error message ready to be used.
Couple things to take care of, looking at your code...
Suggest to catch a more specific exception like SqlException type in addition to the generic exception. Specific exception types always give you more granular information on the error.
Ensure to close connection and dispose off relevant objects in a finally block as catch blocks shortcut your regular flow when exception occurs. using-statements would be much better as it is taken care implicitly.
Here is a sample edit for your code...
public int InsertData(string name, string address)
{
try
{
dobj.InsertTable(name, address);
MessageBox.Show("Record Inserted successfully");
}
catch (SqlException sqlException)
{
var messageBuilder= new StringBuilder();
messageBuilder.AppendLine(sqlException.Message);
foreach(SqlError sqlError in sqlException.Errors)
{
messageBuilder.AppendLine(sqlError.Message);
}
MessageBox.Show("Insertion failed with errors - " + messageBuilder.ToString());
}
catch (Exception exception)
{
MessageBox.Show("Insertion failed with errors - " + exception.Message);
}
}

how to keep logs exception from catch and send logs to database c#?

I want to keep logs exception from catch and send to database or text file ?
try
{
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
thank you
This will create a text file or append the txt if it is already present with the date and time of the exception thrown. I hope this is what your were looking for.
catch(Exception Ex)
{
StreamWriter sw = null;
String Logfile = "C:\ExceptionLog.txt";
if (!System.IO.File.Exists(LogFile))
{
sw = File.CreateText(LogFile);
sw.WriteLine(String.Format("Exception\t DateTime"));
}
else
{
sw = File.AppendText(#"C:\ExceptionLog.txt");
}
sw.WriteLine(String.Format("{0}\t {1}", Ex,
DateTime.Now.ToString("MM/dd/yyy HH:mm:ss"));
sw.Close();
}
Simply, create object of your database context if you are using Entity
framework and insert it in your table(e.g. a table containing(id,
Exception Name, innermessage, error number, CreatedDateTime, etc)).
catch (Exception ex)
{
DatabaseEntity DbObj = new DatabaseEntity();
ExceptionTable ExObj = new ExceptionTable();
ExObj.ExceptionName = ex.Message;
ExObj.InnerException = ex.InnerException;
.....
//Code according to your need
.....
DbObj.ExceptionTable.Add(ExObj);
DbObj.SaveChanges();
MessageBox.Show(ex.Message);
}
you may follow this
How to Log Exception in a file?,
this may help you

MySQL exceptions not caught (C#)

My C# program works with a MySQL database.
For some reason the program cannot catch exceptions caused my the MySQL connection.
Example:
If I make the credentials in the connection string invalid, the program crashes like this (even when running in the debugger): http://imgur.com/SfzkVdW
The connection code is like this:
using MySQLDriverCS;
namespace XXX
{
public class Data
{
private static MySQLConnection con;
static Data()
{
string connectionString = new MySQLConnectionString("XXX",
"XXX",
"XXX",
"XXX").AsString;
con = new MySQLConnection(connectionString + ";CharSet=utf8");
con.Open(); // For testing the connection
con.Close();
}
...
Any ideas for how I can improve things and start catching MySQL exceptions?
I have tried wrapping the code in the static constructor in a try-catch. That didn't help. The program still crashed in the same way.
Thanks.
Same code with the try-catch wrapper. It still fails with the same error: http://imgur.com/SfzkVdW
static Data()
{
try
{
string connectionString = new MySQLConnectionString("XXX",
"XXX",
"XXX",
"XXX").AsString;
con = new MySQLConnection(connectionString + ";CharSet=utf8");
con.Open(); // For testing the connection
con.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Use the appropriate exception type in the catch block.
Use the appropriate MySQL classes.
using MySql.Data.MySqlClient;
// class level var or whatnot:
string connString = #"server=theHostName;userid=dbuser123;password=OpenSesame7;database=my_db_name";
public void connect()
{
try
{
conn = new MySqlConnection(connString); // read above comments for (conn)
conn.Open();
}
catch (MySqlException ex)
{
MessageBoxButtons buttons = MessageBoxButtons.OK;
string s="MySqlException: "+ex.ToString();
MessageBox.Show(s,"Error",buttons);
}
finally
{
if (conn != null)
{
//conn.Close();
}
}
}
Error Caught No Problem:
Add References screenshot:
Catching or handling exceptions in C# generally requires a try-catch statement.
The syntax is essentially as follows:
try
{
// operation likely to cause error
}
catch (Exception e){
// handle error
Console.WriteLine("Exception: " + e);
}
Console.Read();
So wrap your con.Open() logic in a try-catch statement like so:
try
{
Con.Open();
}
catch (Exception e){
// handle error
Console.WriteLine("Possible MySQL Exception: " + e);
}
Additionally, you can add a finally block to the end of a try-catch statement, which executes its code regardless of whether an exception was handled or not:
try
{
// attempt to do something here
con.Open();
}
catch (Exception e){
// handle error
Console.Writeline("Exception: " + e);
}
finally
{
Console.Writeline("This runs no matter if an exception is thrown or not!");
}
Console.Read();

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 :
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")));
}
GetAllStudents(...)
public SqlDataReader GetAllStudents()
{
try
{
return StudentInformationDataAccessLayer.GetStudentInformation();
}
catch (Exception ex)
{
throw ex;
}
}
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;
}
}
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;
}
}
If you want stack trace and exception information to be preserved, you should change the code that re-throws caught exceptions like this:
}
catch(Exception ex)
{
// do what you need to do with ex
// ..
// rethrow..
throw; // notice this is not "throw ex";
}
Re-throwing the exception using just throw; preserves the original stack trace. There won't necessarily be an inner exception but that's not what you should care about. What you need to know is the stack trace of where the exception originated.
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;
}
Not every exception do actually have an inner exception. First check if inner ex is a null and if it is not then process it.
Having said this, you can of course re-throw your exception like below:
catch(Exception ex)
{
// so smth
// ..
// rethrow..
throw;
}
But please remember two things:
Do not type throw ex, just throw.
Do it only if you really want to do something with this exception before rethrowing. If you don't have such a plan, just don't catch it on this level.
I would do something like:
try
{
...
}
catch (Exception ex)
{
if (ex.InnerException == null)
throw ex;
else
throw ex.InnerException;
}
then at some point where you want to do the stack trace, do something along the lines of:
StackTrace trace = new StackTrace(System.Threading.Thread.CurrentThread, true);
StackFrame[] frames = trace.GetFrames();
string result = string.Empty;
foreach (StackFrame sf in frames)
{
string += sf.GetMethod().Name;
}
MessageBox(result);

Exception thrown by page redirection in asp.net

I have this code
protected void Button_Click(object sender, EventArgs e)
{
try
{
// some code
con.Open();
string result = command.ExecuteScalar().ToString();
if (result != string.Empty)
{
// some code
Response.Redirect("Default.aspx");
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
con.Close();
}
It gives an exception from Response.Redirect("Default.aspx");
ex: Thread was being aborted.
any idea why?
thanx
Redirecting from within a Try...Catch statement will result in this Exception being thrown, so this is not what you want to do.
I would update your code to;
string result = string.Empty;
try
{
// some code
con.Open();
result = command.ExecuteScalar().ToString();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
con.Close();
}
if (result != string.Empty)
{
// some code
Response.Redirect("Default.aspx");
}
This is a typical Exception that is thrown by ASP.NET when performing a redirect. It's quite well documented on the Interweb.
Try the following catch block to swallow the exception and all should be fine. It's supposed to do nothing!
catch(ThreadAbortException)
{
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
con.Close();
}

Categories