Catch SQL raise error in C# - c#

I generate the raise error in SQL procedure:
RAISERROR('Already exist',-10,-10)
but I can not catch it using the following code in C#
catch (SqlException ex)
{
bResult = false;
if (ex.Errors[0].Number == -10)
{
CommonTools.vAddToLog("bInsertNewUser", "ManageUsers", ex.Message);
if ((savePoint != null))
savePoint.Rollback();
}
}
How can I catch the raised error in C# ?

RAISERRORs with a SEVERITY value under or equal to 10 are not caught on the C# side because I suppose they are considered just warnings as you can see from the
list at Database Engine Error Severities.
SEVERITY values between 11 and 16 are errors that can be corrected by the user, so, for example, you can try with:
RAISERROR('Already exist',16,1)
Otherwise, you could choose another error code from the list above or, if you really need it, prepare your own custom error message using sp_addmessage.

Your if statement is where things fail. Assuming that the first error in the collection is indeed the one you are looking for (it might not be).
SqlError.Number is not the value that you set in RAISERROR.
Use SqlError.Class to retrieve the severity of the error, or SqlError.State to check the state (both are -10 in your example. so difficult to tell which out you mean):
catch (SqlException ex)
{
bResult = false;
if (ex.Errors[0].Class == -10)
{
CommonTools.vAddToLog("bInsertNewUser", "ManageUsers", ex.Message);
if ((savePoint != null))
savePoint.Rollback();
}
}

Use an error code within 11-16, or just use 16 for a "general" case.
RAISERROR('Already exists',16,1)
Why? Here's my summary of https://learn.microsoft.com/en-us/sql/relational-databases/errors-events/database-engine-error-severities?view=sql-server-2017:
SQL RAISERROR -> C#:
0-10 = fyi*
11-16 = you can fix it**
17-19 = get admin help
20-24 = definitely get admin help***
*(don't throw anything) ┬──┬
**(16 = general)
***(fatal error)

Related

try-catch exception. For some reason the program won't catch any errors

I have tried multiple ways for my program to catch an error by using try get for when the user does not enter any data into the text box for one of the text boxes and for the other when the user does not enter exactly 9 numbers into a text block. I am using C# WPF.
I have tried lots of different methods. one that seemed to work is when i converted to an integer, it seemed to catch it for some reason but i am using strings instead. For example
try
{
// remmeber, textboxes always capture the data as a string therefore we need to convert to an integer
CourseDetails.Name = Convert.ToInt32(txtName.Text);
CourseDetails.SCNnumber = Convert.ToInt32(txtSCNnumber.Text);
}
// if something does go wrong with any of the instructions in the try block then we will catch the error rather than crash the program
catch (Exception)
{
MessageBox.Show("Please complete all fields");
return;
}
try
{
if (txtName.Text.Length < 0)
{
MessageBox.Show("Enter your full name");
}
else
{
CourseDetails.Name = txtName.Text;
}
if (txtSCNnumber.Text.Length != 9)
{
MessageBox.Show("SCN number must be 9 characters long");
}
else
{
CourseDetails.SCNnumber = txtSCNnumber.Text;
}
}
catch (Exception)
{
MessageBox.Show("Please complete all fields");
}
The result I'm looking for is when a user inputs data into the first text box for their name it should save to the variable CourseDetails.Name otherwise if they leave it blank the program will catch this as an error an display a message.
for the second text box if the user enters anything other than 9 characters then the program will display an error message stating that the phone number must be more than 9 characters. otherwise the program will save the users input into the variable CourseDetails.SCNnumber
A try-catch block catches exceptions. To catch an exception, an exception has to be thrown. Your first try-catch block will work, because Convert.ToInt32 will throw an FormatException if the input is invalid as documented here.
To make the second try-catch block work, you have to throw an exception on invalid input.
try
{
if (txtName.Text.Length < 0)
{
throw new ValidationException("Please enter user name")
}
// ...
}
catch(ValidationException ex)
{
MessageBox.Show(ex.Message);
}
As you see i catch on a specific exception type. Is it generally bad practise to catch on the Exception type as you may catch exceptions you can't handle proper inside that catch block. Swallowing those can increase the debigging difficulty significantly.
I would also note Exceptions are not the perfect way to perform more complex validation logic, since a throw jumps right to the next matching catch, so not all fields will be validated.
You have to understand what Try-Catch blocks are used for. Their primary role is to handle exceptions in your program. These exceptions can be compiler exceptions which is thrown by the CLR or program code if there is an error in the program. These exceptions need to be handled to prevent crashing of program. C# provides built-in support to handle the exception using try, catch & finally block.
Now in your code, don't show your MessageBox.Show in your Exception block. What this basically means is that only when an exception is thrown, then your MessageBox will display. This exception (in reference to your code) would be if there is an incorrect conversion of Integer of your txtName.Text.
Instead use If-Else conditions in your scenario. For example:
//Try to parse your captured data to Integer
try
{
if(txtName.Text == "" && txtSCNnumber.Text == "")
{
MessageBox.Show("Please complete all fields");
}
else
{
// remmeber, textboxes always capture the data as a string therefore we need to convert to an integer
CourseDetails.Name = Convert.ToInt32(txtName.Text);
CourseDetails.SCNnumber = Convert.ToInt32(txtSCNnumber.Text);
}
}
//If the parse fails, then throw an exception
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Thanks for your input guys. I decided to leave the Try-Catch out after reading your comments I realised it wasn't fit for what I was trying to do. I kept it simple with If-Else statements as shown below.
if (txtName.Text == "" && txtSCNnumber.Text == "")
{
MessageBox.Show("Please complete all fields");
txtName.Focus();
}
else if (txtSCNnumber.Text.Length != 9)
{
MessageBox.Show("You have entered an invalid SCN number");
txtSCNnumber.Focus();
}
else
{
CourseDetails.Name = txtName.Text;
CourseDetails.SCNnumber = txtSCNnumber.Text;
}

Linq to SQL - SubmitChanges() - Check if insert was successful

I have following code -
public bool InsertUser(params)
{
User objUser = new User(params);
objDataContext.Users.InsertOnSubmit(objUser);
objDataContext.SubmitChanges();
return objUser.Id >= 0;
}
Calling method -
if (!_database.InsertUser(params))
{
//WriteErrorMessage
}
As I understand from various posts that if we want to know whether an insert was successful or not, we should check if any exception is being thrown.
However above code is relying on whether newly inserted Id is >=0 or not.
Can please guide -
If I should change above code and add a try-catch instead?
Is there any possible scenario where no error is thrown by SubmitChanges() but newly inserted Id <= 0 ?
Thank you!
If I should change above code and add a try-catch instead?
No, don't do that as in that case you will not be able to get the exact reason of failure. If you catch it then the information of failure will be lost and will not propogate to the user.
However if you think that giving exception to the user is not a good idea and you need to catch it then simply place it inside the try catch like this:
public bool SubmitChanges()
{
try{
//your code
db.SubmitChanges();
return true;
}
catch(Exception e)
{
// some code to catch exception
return false;
}
}
Is there any possible scenario where no error is thrown by SubmitChanges() but newly inserted Id <= 0 ?
If you are getting the value >=0, then there is no point to worry about this.
You can also use the GetChangeSet like this:
Gets the modified objects tracked by DataContext.
ChangeSet cs = db.GetChangeSet();
Console.Write("Changes: {0}", cs);
if your code execute the line objDataContext.SubmitChanges(); and comes on return objUser.Id >= 0; your insert will be successfull. you don't need to worry after that. let sql server and your compiler take care of the rest
Yes can use try catch to efficiently catch the error and display appropriate messages.

How to catch multiple exceptions on SaveChanges() or is it possible?

I get an XML file(from an infopath form), create an object and insert that object into the DB. Im using a C# webservice to do this parsing and it returns true if successful and currently it returns the exception message if the SaveChanges() fails. The main exceptions I'd like to return are the DbEntityValidationExceptions as I'll handle other exceptions differently. Some of the columns have max lengths so is the field exceeds that I want to return the field name that they need to edit. Can I catch all the DbEntityValidationException for all fields that failed or does entity only throw the first exception and then rollback the transaction? With 200 fields it'd be nice to tell the user which fields they need to change versus the first field and then continue to fail as they fix the single exception each time.
If it is not possible my proposed solution below is irrelevant and should be removed. If it is possible to return all the Exceptions, what am I doing wrong?
exceptionList = new List<string>();
try
{
db.SaveChanges();
}
catch (Exception ex)
{
if (ex.GetType() == new DbEntityValidationException().GetType())
{
DbEntityValidationException eValidEx = (DbEntityValidationException) ex;
foreach (DbEntityValidationResult vResult in eValidEx.EntityValidationErrors)
{
foreach (DbValidationError vError in vResult.ValidationErrors)
{
exceptionList.Add(vError.ErrorMessage);
}
}
result = false;
}
else
{
exceptionList.Add("Unknown. " + ex.Message);
}
}
You need custom exception which inherit Exception. In this exception you have property for example Errors. This property will be message collection.
When you are trying to save changes, you should know what kind of fields you are expecting. You should define in other class boundaries of the fields(example Price->decimal, mandatory, maxValue and so on) On save you should check the boundaries if one of them is not true you should add message string in Errors of the custom exception(example Price is not decimal field)
On the end if the Errors.Count > 0 thorw the CustomException. You should override the message property in the CustomException -> loop all the Errors and return the text of all of them. At the end you need only customException.Message and you will have all the problems shown to the user.
I Hope this helps.
So when you catch an exception like that, you'll only catch the first exception. Java doesn't let you keep going on when you have a bunch of Exceptions and to catch all of them.
What you could do is put the entire thing in a while loop that keeps going until you've saved all of the changes. Make sure in the try{} block that you iterate through each field instead of just trying the first field again and again.

C# if exception is caught will it reach my return statement?

In System.IO there is a function:
string File.ReadAllText( string path );
I am trying to write a function that would call File.ReadAllText, take care of all possible exceptions and return true/false and store error message.
What I have is this:
public static class FileNoBS
{
public static bool ReadAllText( string path, out string text, out string errorMessage )
{
errorMessage = null;
text = null;
bool operationSuccessful = false;
try
{
text = System.IO.File.ReadAllText( path );
operationSuccessful = true;
}
catch ( ArgumentNullException e )
{
errorMessage = "Internal software error - argument null exception in FileNoBs.ReadAllText\nMessage: " + e.Message;
}
catch ( ArgumentException e )
{
errorMessage = "Internal software error - path is a zero-length string, contains only white space, or contains one or more invalid characters as defined by InvalidPathChars in FileNoBs.ReadAllText.\nMessage: " + e.Message;
}
catch ( PathTooLongException e )
{
errorMessage = "The specified path was too long.\nMessage: " + e.Message;
}
catch ( DirectoryNotFoundException e )
{
errorMessage = "The specified directory was not found.\nMessage: " + e.Message;
}
catch ( FileNotFoundException e )
{
errorMessage = "The file specified in path was not found.\nMessage: " + e.Message;
}
catch ( IOException e )
{
errorMessage = "An I/O error occurred while opening the file.\nMessage: " + e.Message;
}
catch ( UnauthorizedAccessException e )
{
errorMessage = #"UnauthorizedAccessException
path specified a file that is read-only.
-or-
This operation is not supported on the current platform.
-or-
path specified a directory.
-or-
The caller does not have the required permission.\nMessage: " + e.Message;
}
catch ( NotSupportedException e )
{
errorMessage = "path is in an invalid format.\nMessage: " + e.Message;
}
catch ( SecurityException e )
{
errorMessage = "You do not have the required permission.\nMessage: " + e.Message;
}
return operationSuccessful;
}
}
I don't understand how how control flow goes with functions that return value.
Let's say UnauthorizedAccessException gets caught, errorMessage is set to
errorMessage = "You do not have the required permission..."
I know that finally gets executed every time, but compiler won't let me do return inside finally block. So will my return get reached or not?
Another question is how to simplify this while still following official guidelines:
"In general, you should only catch those exceptions that you know how to recover from. "
I dread going through all functions that I will need from File class (Move, Copy, Delete, ReadAllText, WriteAllText) and then Directory class and doing all these long blocks of code just to catch all exceptions I don't care about and not catch too many of them cause Microsoft says it's bad.
Thank you.
EDIT: I got comments like this is not handling exceptions this is "something else".
I am client for my code and I want to do something like this:
if ( !FileNoBS.ReadAllText( path, text, errorMessage ) ) {
MessageBox.Show( errorMessage );
return;
}
// continue working with all errors taken care of - don't care for whatever reason file wasn't opened and read, user is notified and I am moving on with my life
Your return will be reached as there isn't a return in the try block or the catch block.
Generally, you only want to catch exceptions that you expect may occur and have a way of handling them. For example, you may want to handle the file not being found from the given path and return a default file instead. You should allow other exceptions not to be caught so you know that something unexpected has happened and not hide it by catching all exceptions.
As I said in my comment, you are better off handling the exceptions at a higher level and simply displaying the exception message rather than manually setting each message. I think in this case the message from the exception will be descriptive enough.
public static class FileNoBS
{
public static string ReadAllText(string path)
{
return System.IO.File.ReadAllText( path );
}
}
then use it like this at some higher level in your application. I typically have a general handler to handle all application exceptions and log them and display a message box if necessary.
try
{
var text = FileNoBS.ReadAllText("file.ext");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
Instead of catching the exceptions you should try to avoid the situation that will lead to those exceptions being thrown in the first place. In your case you should have some input validation before calling ReadAllText
never accept a path that is null - you know this will lead to an exception so handle it before it does
never accept a path that leads to a file that does not exist - use File.Exists(path) prior to the call
never accept a malformed path E.g. the empty string or one with invalid characters - this will lead to an exception
These tests should be performed where the input originates. That is if the user types them in, validate them before using them. If they come from a DB or somewhere else validate there before use. If it's not user input they are all indications of a system error and should be treated as such, not as something the user should worry about.
Security exceptions can be somewhat harder to test up front and in many cases it is exceptional to get a violation and therefor perfectly ok to get an exception. It shouldn't crash the program of course but be handled with an errormessage to the user (if it's based on user input, if it's system generated data that leads to this, it's an idication of a system error that should be fixed at code level). It's often more appropriate to do this where the call happens than in some library method.
for IOExceptions they can be put into two buckets. Recoverable once (usually a retry) and unrecoverable once. As a minimum give the user feedback on the exception, so the user might have the option of retrying.
A very general rule that should be part of the error correction logic is to never have invalid data floating around the system. Make sure that all objects manage the invariants (Tools are available for this such as code contracts). Reject invalid input from the user (or other systems) when they are received instead of when they result in an exception.
If you do all the input validation and still have E.g. ArgumentNullException then that points to an error in the logic of the program, something that you want to be able to easily find in a test and correct before you release the bug. You shouldn't try and mask this error.
Provided no other error occurs, yes.
I'd add at the end:
catch (Exception e)
{
errormessage = "An unexpected error has occured.";
}
return operationSuccessful;
Though, this will always return the successful even if you got an error. I'm not sure if that's what you want, or if your variables are badly named.
The return statement is going to be called in case of any exception in your code, before it is placed at the end of the program before it exits.
I will suggest placing a single exception handler with a high level Exception type, like the 'Exception' type itself, and print or log the exception message. Specifying so many exception handlers in each method is going to take a lot of energy which your should actually put in the method itself.
try
{
return ReadAllText("path", "text", "error");
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
return false;
So if the method gets called, it will return immediately, otherwise the exception gets printed/logged and the method will return false.
You can however, mention a couple or few explicit exception handlers in some cases, where you think it will be beneficial.
Yes It will return the value.
But, better you handle return value in finally statement.
If in any case you want to return operationSuccessful value, then write finally block after catch blocks as follows,
finally
{
return operationSuccessful;
}

Why use finally in C#?

Whatever is inside finally blocks is executed (almost) always, so what's the difference between enclosing code into it or leaving it unclosed?
The code inside a finally block will get executed regardless of whether or not there is an exception. This comes in very handy when it comes to certain housekeeping functions you need to always run like closing connections.
Now, I'm guessing your question is why you should do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}
When you can do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
alwaysDoThis();
The answer is that a lot of times the code inside your catch statement will either rethrow an exception or break out of the current function. With the latter code, the "alwaysDoThis();" call won't execute if the code inside the catch statement issues a return or throws a new exception.
Most advantages of using try-finally have already been pointed out, but I thought I'd add this one:
try
{
// Code here that might throw an exception...
if (arbitraryCondition)
{
return true;
}
// Code here that might throw an exception...
}
finally
{
// Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}
This behaviour makes it very useful in various situations, particularly when you need to perform cleanup (dispose resources), though a using block is often better in this case.
Because finally will get executed even if you do not handle an exception in a catch block.
any time you use unmanaged code requests like stream readers, db requests, etc; and you want to catch the exception then use try catch finally and close the stream, data reader, etc. in the finally, if you don't when it errors the connection doesn't get closed, this is really bad with db requests
SqlConnection myConn = new SqlConnection("Connectionstring");
try
{
myConn.Open();
//make na DB Request
}
catch (Exception DBException)
{
//do somehting with exception
}
finally
{
myConn.Close();
myConn.Dispose();
}
if you don't want to catch the error then use
using (SqlConnection myConn = new SqlConnection("Connectionstring"))
{
myConn.Open();
//make na DB Request
myConn.Close();
}
and the connection object will be disposed of automatically if there is an error, but you don't capture the error
Finally statements can execute even after return.
private int myfun()
{
int a = 100; //any number
int b = 0;
try
{
a = (5 / b);
return a;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return a;
}
// Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected"
finally
{
Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above
}
Response.Write("Statement after return after finally"); // -->Unreachable code
}
finally, as in:
try {
// do something risky
} catch (Exception ex) {
// handle an exception
} finally {
// do any required cleanup
}
is a guaranteed opportunity to execute code after your try..catch block, regardless of whether or not your try block threw an exception.
That makes it perfect for things like releasing resources, db connections, file handles, etc.
i will explain the use of finally with a file reader exception Example
with out using finally
try{
StreamReader strReader = new StreamReader(#"C:\Ariven\Project\Data.txt");
Console.WriteLine(strReader.ReadeToEnd());
StreamReader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
in the above example if the file called Data.txt is missing, an exception will be thrown and will be handled but the statement called StreamReader.Close(); will never be executed.
Because of this resources associated with reader was never released.
To solve the above issue, we use finally
StreamReader strReader = null;
try{
strReader = new StreamReader(#"C:\Ariven\Project\Data.txt");
Console.WriteLine(strReader.ReadeToEnd());
}
catch (Exception ex){
Console.WriteLine(ex.Message);
}
finally{
if (strReader != null){
StreamReader.Close();
}
}
Happy Coding :)
Note:
"#" is used to create a verbatim string, to avoid error of "Unrecognized escape sequence".
The # symbol means to read that string literally, and don't interpret control characters otherwise.
Say you need to set the cursor back to the default pointer instead of a waiting (hourglass) cursor. If an exception is thrown before setting the cursor, and doesn't outright crash the app, you could be left with a confusing cursor.
Sometimes you don't want to handle an exception (no catch block), but you want some cleanup code to execute.
For example:
try
{
// exception (or not)
}
finally
{
// clean up always
}
The finally block is valuable for cleaning up any resources allocated in the try block as well as running any code that must execute even if there is an exception. Control is always passed to the finally block regardless of how the try block exits.
Ahh...I think I see what you're saying! Took me a sec...you're wondering "why place it in the finally block instead of after the finally block and completely outside the try-catch-finally".
As an example, it might be because you are halting execution if you throw an error, but you still want to clean up resources, such as open files, database connections, etc.
Control Flow of the Finally Block is either after the Try or Catch block.
[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]
with Exception
1 > 2 > 3 > 4 > 5
if 3 has a Return statement
1 > 2 > 3 > 4
without Exception
1 > 2 > 4 > 5
if 2 has a return statement
1 > 2 > 4
As mentioned in the documentation:
A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.
It is also worth reading this, which states:
Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.
So it is clear that code which resides in a finally clause will be executed even if a prior catch clause had a return statement.

Categories