I'd like my code to give a warning or something whenever the database is not available.
(That's why I commented the connection string), but my website just crashes.
I created this class cause there were many parts of the program using this connection string (login page, register page, user panel page, etc), so if I want to change something in the future, this is the only string I have to change.
namespace Fatture.Data.User
{
public class DbConnection
{
public MySqlConnection ConnessioneDb()
{
MySqlConnection conn = new MySqlConnection(/*ConfigurationManager.ConnectionStrings["ConnectionStringloginDb"].ConnectionString*/);
try
{
conn.Open();
}
catch (Exception ex)
{
throw new Exception("I can't connect to the database", ex);
}
return conn;
}
}
}
Use exception handling...
var connector = new DbConnection();
try
{
var connection = connector.ConnessioneDb();
}
catch (Exception ex)
{
// show message to user: database not available
}
Though you'll have to put this in place everywhere you access the database. Instead you can also just set up error handling for your entire site.
Catch the exception...
try
{
var conn = new DbConnection().ConnessioneDb();
}
catch (Exception ex)
{
// Notify user here
}
Related
I am writing a client application using System.Data.OracleClient. With an error in writing a select query when calling the OracleDataAdapter.Fill (DataSet) function, I understand that an error occurs inside, but the program, when executing this function, interrupts the execution of the body of the function in which this string is located. Binding OracleDataAdapter.Fill Error event or "try" construct does not fire.
How can I catch errors like this?
string select = "SELECT qwe FROM employee"; // 'employee' does not contain 'qwe'
OracleDataAdapter adapter = new OracleDataAdapter(select, connection);
adapter.FillError += Adapter_FillError;
try
{
adapter.Fill(ds, "zak");
}
catch (OracleException ex)
{
MessageBox.Show(ex.Message);
}
private void Adapter_FillError(object sender, FillErrorEventArgs e)
{
MessageBox.Show(e.Errors.Message);
}
I have a (Windows Forms) app that will be installed on various users' desktops; it will allow them to generate reports based on custom code that connects to a SQL Server Database and reads records from certain tables.
The Connection String is:
Data Source=PLATYPUS;Initial Catalog=Duckbills;Persist Security Info=True;User ID=lilabner;Password=d0GpAtCh42;Connect Timeout=120
I understand this to mean that if all the following is true:
The user's machine has the SQL Server client software installed
The SQL Server client has been configured to access the PLATYPUS database
The table "Duckbills" exists in that database
The username and password are what is expected
...then the connection will be successful.
In the event any of the above equate to false, I want to show the user a "user-friendly" message informing them, in plain English, what the problem is and what to do about it. How can I test for these various problems so that the most appropriate message is shown the user in the event of connection failure.
Here is the pertinent existing code:
DataSet dsUsage = new DataSet();
SqlConnection conn =
new SqlConnection("SERVER=PLATYPUS;DATABASE=Duckbills;UID=lilabner;PWD=d0GpAtCh42;Connection Timeout=0");
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "Exec sp_ViewPlatypi";
da.SelectCommand = cmd;
conn.Open();
da.Fill(dsUsage);
conn.Close();
DataTable dtUsage = dsUsage.Tables[0];
if (dtUsage.Rows.Count > 0)
{
foreach (DataRow productUsageByMonthDataRow in dtUsage.Rows)
{
. . .
catch (Exception ex)
{
String exDetail = String.Format(PlatypusConstsAndUtils.ExceptionFormatString, ex.Message, Environment.NewLine, ex.Source, ex.StackTrace);
MessageBox.Show(exDetail);
}
As you can see, I have a "catch all" (no pun intended) Catch block. I want something like:
catch (SQLServerException sex)
{
MessageBox.Show("SQL Server not available - go tell the DBA");
}
catch (NoTableException ntex)
{
MessageBox.Show("Go tell the DBA there's no such table");
}
catch (BadPwdException sex)
{
MessageBox.Show("Your username and/or password are bad - go tell it to the Marines");
}
catch (Exception ex)
{
String exDetail = String.Format(PlatypusConstsAndUtils.ExceptionFormatString, ex.Message, Environment.NewLine, ex.Source, ex.StackTrace);
MessageBox.Show(exDetail);
}
...but I don't know, first if all, if it's even possible to get that granular with connection exception messages, and secondly - if it is - just what the corresponding Exception types are.
Strip your code back to handle Exception (catch (Exception ex)). Then, put a break point in your catch block. Attach the debugger to your code and when it hits the catch block, drag the ex variable in to your watch window. There, you will see all the details of the exception and you can determine what you need to be able to better handle the various exceptions that come up.
Based on MethodMan's suggestion and TheShaman's link, I adapted that code to this:
catch (SqlException sex)
{
for (int i = 0; i < sex.Errors.Count; i++)
{
String sexDetail = String.Format("SQL Exception #{0}{1}Source: {2}{1}Number: {3}{1}State: {4}{1}Class: {5}{1}Server: {6}{1}Message: {7}{1}Procedure: {8}{1}LineNumber: {9}",
i+1, // Users would get the fantods if they saw #0
Environment.NewLine,
sex.Errors[i].Source,
sex.Errors[i].Number,
sex.Errors[i].State,
sex.Errors[i].Class,
sex.Errors[i].Server,
sex.Errors[i].Message,
sex.Errors[i].Procedure,
sex.Errors[i].LineNumber);
MessageBox.Show(sexDetail);
}
}
catch (Exception ex)
{
String exDetail = String.Format(UsageRptConstsAndUtils.ExceptionFormatString, ex.Message, Environment.NewLine, ex.Source, ex.StackTrace);
MessageBox.Show(exDetail);
}
And for an example of what this produces:
public partial class Variables_input : System.Web.UI.Page
{
public string conStr = WebConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
protected void Buttonsubmit_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection(conStr))
{
try
{
con.Open();
Response.Write("<script language ='javascript'>alert('Connection is open');</script>");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Response.Write("<script language ='javascript'>alert('Connection Problem');</script>");
}
finally
{
con.Close();
Response.Write("<script language ='javascript'>alert('Connection is close');</script>");
}
}
}
I am not able to connect to connect my SQL Server database. After running this code I receive "Connection Problem". Please help.
I don't know where to begin to start.
You are using SQL server not mySQL right, you have funny wording. Just want to make sure.
You might want to try looking at the exception data, usually it gives you an error message. You caught the error now read it.
If the error message is not helpful you could put a breakpoint at con.Open() and step into an make sure all the parameters are correct or see where the problem is if the exception error doesn't help.
Might also want to look at this:
dot net pearl for sqlconnection
I`ve used a function to open sql connection and generate a command.So I don`t use using for them.
But what happens if I get an exception ?while catch the exception nedd I explicitly dispose them?
using translates into try-finally block. If you don't want to use using statement then you can mimic the same using try-finally, in your case with catch just have finally block and dispose the connection there. Something like:
{
SqlConnection conn = new SqlConnection("your connection string");
try
{
//your code
}
catch (SqlException se)
{
//handle particular exception first
}
catch (Exception ex)
{
//handle all other exceptions
}
finally
{
if (conn != null)
conn.Dispose();
}
}
That will ensure the disposal of connection in case of an exception and normal flow (when no exception occurs)
I am writing an application in which when something happened to the connection I want to pop up a messagebox and show the user the error...
for this purpose when the program throw an exception it will come to the catch block and in that I want to show the user the message here is the code :
catch (WebException ex)
{
if (!(ex.Message == "The operation has timed out."))
{
MessageBox.Show(ex.Message);
}
}
As it seems the program will come to this catch something like forever till the connection is become fixed so what should I do to update my message on just one messagebox at a time?
There is not much control over MessageBox when it's displayed. I would use another Form displayed in a modal mode. Before displaying, you can start a separate thread and put the logic to monitor the connection. When re-established, notify the message form and close it.
You can use something like:
public static class FailureMessagebox
{
private static bool _hasBeenSuccessful = true;
public static void ShowIfFailure(Action someAction)
{
try
{
someAction();
_hasBeenSuccessful = false;
}
catch (Exception err)
{
if (_hasBeenSuccessful)
MessageBox.Show(ex.Message);
_hasBeenSuccessful = false;
throw;
}
}
}
Sample usage:
try
{
WebResponse response;
FailureMessagebox.ShowIfFailure(() => response = webRequest.GetResponse());
}
catch (WebException err)
{
//handle the exception here.
}