SqlException logs RAISEERROR and PRINT statements from .NET [duplicate] - sql-server

I have a stored procedure in SQL Server that throws an error whenever a condition is hit. In order to catch this error and display it to the user, I use
try
{
//code
}
catch (Exception e)
{
return BadRequest(e.Message);
}
This catches most of the cases but on the other hand, this procedure has some print messages that also get caught by this Exception. Is there a way to catch the exception thrown only from RAISERROR and ignore this print message from SQL Server?

All info and error messages generated during command execution are buffered and available when a SqlException is caught. The Message property includes the text of all info messages (print statements and errors with a severity of less than 11) and the warnings/errors that caused the exception.
To ignore info messages, use the SqlException Errors collection and process only those with severity (SqlError.Class property) of 11 or higher:
catch (SqlException e)
{
var sb = new StringBuilder();
foreach(var error in e.Errors)
{
if(error.Class > 10) sb.AppendLine(error.message);
}
return BadRequest(sb.ToString());
}

Related

How to Implement Retry analyzer in try catch Block?

Below is my code after got the exception immediately it should trigger one more time for execution but didn't execute.Without try,catch it was executing but after keep the code in try and catch RetryAnalyzer is not working as expected please anyone help me how to implement RetryAnalyzer in try,catch block
#Test(priority=4,enabled=true,retryAnalyzer=RetryAnalyzer.class)
public void TC_04() throws InterruptedException
{
try
{
extent=new
ExtentReports("/Users/anakin/workspace/Reports/MKE.html");
Login_Objects.Switch_PB2U(driver).click();
String screenshot_path = Screenshot.createScreenshot(driver);
String image = log.addScreenCapture(screenshot_path);
log.log(LogStatus.PASS, "To Stocks",image);
extent.endTest(log);
driver.closeApp();
}
catch(Exception e)
{
String screenshot_path = Screenshot.createScreenshot(driver);
String image = log.addScreenCapture(screenshot_path);
log.log(LogStatus.FAIL, "Verify Suggest Stocks ", image);
extent.endTest(log);
}
}
Catching exception in your complete test code is a bad practice. Even as in your case you are capturing screenshot in case of failure, you should use listener than catching exception.
Since retry analyzer works for failed tests, and you are cathing exceptions and thus supressing the errors, it might give the impression that your test never failed and thus the retryAnalyzer is not working.
Solution : Move code in Exception to Listeners and remove unnecessary Exception handling.

NLog - How to prevent site from crashing when database throws error

We currently use NLog in our website to log messages into an MSSQL database, instead of a regular log file.
How can we configure NLog to ignore any database errors instead of crashing the website when the database cannot be found?
Using a Try, Catch clause is used often with catching Database Exceptions from Invalid Operations to Connectivity issues. NLog seems to handle exception logging pretty efficiently and I would Log these at Error Level. The following is my production code(not exactly) and it seems to handle both object level errors and database errors.
try
{
//Database Operations...
}
catch (SqlException sqlException)
{
logger.Error(sqlException, "Sql exception caught while Importing.");
}
catch (NullReferenceException nullRefException)
{
try
{
DBConnTxn.ConnectDB();
DBConnTxn.ExecuteUpdateQuery("ROLLBACK TRAN");
DBConnTxn.DisconnectDB();
logger.Error(nullRefException, "Null Reference exception caught while Importing.");
}
catch(Exception ex)
{
logger.Error(ex, "DB Roll Back Exception while importing.");
return false;
}
return false;
}
catch (ArgumentException argsException)
{
try
{
DBConnTxn.ConnectDB();
DBConnTxn.ExecuteUpdateQuery("ROLLBACK TRAN");
DBConnTxn.DisconnectDB();
}
catch { }
logger.Error(argsException, "Null Reference exception caught while Importing.");
FullAutoMailSendHelper.ProcessErrors.Add("Data Import Error", argsException.Message);
return false;
}
catch (Exception ex)
{
try
{
logger.Fatal(ex, "Unhandled Exception occurred");
DBConnTxn.ConnectDB();
DBConnTxn.ExecuteUpdateQuery("ROLLBACK TRAN");
DBConnTxn.DisconnectDB();
}
catch(Exception innerException) {
}
FullAutoMailSendHelper.ProcessErrors.Add("Data Import Error",ex.Message);
return false;
}

ServiceStack OrmLite and transactions

I am trying to execute sql inside a transaction using ServiceStack OrmLite. The code below works with Sqlite but not with SqlServer. With SqlServer I get the following error:
ExecuteScalar requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.
Is there something wrong with this code?
using (var trans = Db.BeginTransaction())
{
try
{
foreach (myObject in myObjects)
Db.Insert<MyObject>(myObject);
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
Someone else put this answer in a comment and then deleted it... so:
BeginTransaction needs to be OpenTransaction

Objectify 4 transactions

With Objectify 4 I am trying to throw a controlled exception inside a transaction. As vrun() interface does not allow throwing exceptions, I have to catch it. I do it, and then I want to perform the rollback, but when the transaction finishes and it all fails (I think it is because it tries to do a commit), not even doing the rollback. How can I do it?
Thanks in advance!
Code example:
ofy().transact(new VoidWork() {
#Override
public void vrun() {
//do something
//...
//find someting wrong and want to throw an exception
try {
throw new MyException(); //throw the exception
} catch (MyException e) {
ofy().getTransaction().rollback(); //catch it and perform rollback
}
}
});
//an error occurs

ZombieCheck Exception - This SqlTransaction has completed; it is no longer usable -- during simple commit

I have the following code which performs a commit of a single row to a database table (SQL 2008 / .NET 4)
using (var db = new MyDbDataContext(_dbConnectionString))
{
Action action = new Action();
db.Actions.InsertOnSubmit(dbAction);
db.SubmitChanges();
}
Normally everything is fine, but once in a while I get the following exception:
System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable.
at System.Data.SqlClient.SqlTransaction.ZombieCheck()
at System.Data.SqlClient.SqlTransaction.Rollback()
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
There are a number of similar questions on SO but I after reading them I cannot work out the cause.
Could this be simply due to a SQL timeout (the exception occurs close to 25s after the call is made)? Or should I expect a SQL timeout exception in that case?
Does anyone know what else may cause this?
The DataContext.SubmitChanges method has the following code lines in it's body:
// ...
try
{
if (this.provider.Connection.State == ConnectionState.Open)
{
this.provider.ClearConnection();
}
if (this.provider.Connection.State == ConnectionState.Closed)
{
this.provider.Connection.Open();
flag = true;
}
dbTransaction = this.provider.Connection.BeginTransaction(IsolationLevel.ReadCommitted);
this.provider.Transaction = dbTransaction;
new ChangeProcessor(this.services, this).SubmitChanges(failureMode);
this.AcceptChanges();
this.provider.ClearConnection();
dbTransaction.Commit();
}
catch
{
if (dbTransaction != null)
{
dbTransaction.Rollback();
}
throw;
}
// ...
When the connection times out, the catch block is executed and the dbTransaction.Rollback(); line will throw a InvalidOperationException.
If you had control over the code, you could catch the exception like this:
catch
{
// Attempt to roll back the transaction.
try
{
if (dbTransaction != null)
{
dbTransaction.Rollback();
}
}
catch (Exception ex2)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
throw;
}
YES! I had the same issue. The scary answer is that SQLServer sometimes rolls back a transaction on the server side when it encounters an error, and does not pass the error back to the client. YIKES!
Look on the Google Group microsoft.public.dotnet.framework.adonet for "SqlTransaction.ZombieCheck error" Colberd Zhou [MSFT] explains it very well.
and see aef123's comment on this SO post
May I suggest that connection closes earlier that transaction commits. Then the transaction is rolled back. Check this article on MSDN Blog.

Resources