EntityFramework exception: How can i see the real query - mysql

Sometimes i have an EntityFramework exception where calling SaveChanges.
I see this kind of message: "An error occurred while updating the entries. See the inner exception for details."
I have logged the stack trace, the inner exception and stuff but there is no clear explanation of the problem. I would like to see the real query (it is a mysql database), with the parameters. Do you know how i can see or log the real query ?
Thanks

You can use DbEntityValidationException handler which will let you know what was wrong precisely.
try{
//Your code here
}
catch (DbEntityValidationException ex)
{
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
var fullMessageError = string.Join("; ", errorMessages);
var exceptionMessage = string.Concat(ex.Message, "Exact Message " + fullMessageError);
}
catch (Exception ex)
{
//General Exception here
}

You can set log property of dbContext.Database and log the actual queries generated by EF.
using (var context = new MyDBContext())
{
context.Database.Log = Console.Write; // This is where you setup where to log queries
// Your code here...
}
There is a detailed documentation on MSDN https://msdn.microsoft.com/en-us/data/dn469464.aspx

Related

How can i cover Junit test for an Exception's root cause?

I have the following block of code for which I want to increase code coverage:
try{
discountReferenceCustomerRepository.saveAllAndFlush(discountReferenceCustomersNew);
} catch (DataIntegrityViolationException ex) {
if(ex.getRootCause() != null && ex.getRootCause().toString().contains("Duplicate entry")){
LOGGER.error("{}::{}:: Attempt to persist duplicate data : [{}]", CdfConstants.CDF_CORE_SERVICE_NAME, DUPLICATE_DATA_ERROR, ex);
throw new SystemException("Attempt to persist one or more duplicate records ",ERROR_MSG_DUPLICATE_DATA);
} else {
throw ex;
}
}
return new ResponseStatusVO("Added new ORG to existing RCD for given EA");
}
I am unable to cover the "ex.getRootCause()" section, because in my Junit test, all i do is:-
when(repository.saveAllAndFlush(any())).thenThrow(new DataIntegrityViolationException("test"));
The root exception is SQLIntegrityConstraintViolationException with the message that says "Duplicate Entry". This error is then propagated by DataIntegrityViolationException which i can catch in my code.
Obviously, i am unable to do something like "ex.setRootCause" in my Junit coz there ain't such api defined in the library.
What can i do to increase coverage ?

Exception details in ABP framework

I wanna return the details of exception with ABP .NET Core, what I noticed is when I go to AbpAuditLogs table and App_Data\Logs logFile they contain the exception in details but when I use below method to return the exception it shows only general exception without any details (500 Internal Server Error)
try{
:
:
:
}
catch (Exception ex)
{
throw new System.ArgumentException(ex.InnerException.Message.ToString(), "original");
}
So, How could I return the specific Exception for the user for Example Email Validation Exception and so on?
Update:
I will explain more to make the question more clear :
The way that I handled the exception is attached with this question above .
The problem is when hitting a request on the service from swagger or Postman always see General Error with status Code 500 without any details and that force me to review the details of the exception from Log File or Log Table , I wanna see the details of the exception (e.g FileNotFoundException ) directly from Swagger or Postman without return back to Log File or AbpAuditLogs Table.
I think User Friendly Exception will work for you.
Because if an exception implements the IUserFriendlyException interface, then ABP does not change it's Message and Details properties and directly send it to the client.
throw new UserFriendlyException(
"Username should be unique!"
);
You can find more information here.
Actually, I found the answer in this question for #Mehdi Daustany .what I did is exactly what #Mehdi Daustany answered, I've added below code :
if (_env.EnvironmentName.ToLower() == "development")
Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;
under ***.Web.Core then the details of exception appeared in the Swagger
services.Configure<AbpExceptionHandlingOptions> (options =>
{
options.SendExceptionsDetailsToClients = true;
});
Above code will configure abp to return all the exception details. Just add it to the configuration.

Show SQL error Message in AngularJS

I'm trying to create an application where the user can explicitly see the SQL rules they're violating if they enter a bad input to be persisted or used to query the database. I would like to show this as a popup message on the browser, also I'm using AngularJS on the client side and SpringBoot on the backend. I've seen the post where they are discussing how to print it on the console,
Show SQL error message.
public static void printSQLException(SQLException ex) {
for (Throwable e : ex) {
if (e instanceof SQLException) {
if (ignoreSQLException(
((SQLException)e).
getSQLState()) == false) {
e.printStackTrace(System.err);
System.err.println("SQLState: " +
((SQLException)e).getSQLState());
System.err.println("Error Code: " +
((SQLException)e).getErrorCode());
System.err.println("Message: " + e.getMessage());
Throwable t = ex.getCause();
while(t != null) {
System.out.println("Cause: " + t);
t = t.getCause();
}
}
}
}
}
But in that question it is showing how to retrieve it in the console, not the browser. By default the HttpError message is from SpringBoot where it gives a BadSQLGrammarExcpetion. I require the exact SQLError Message to show the actual error that occurs on the database. I'm a bit new to AngularJS since I'm mainly a backend developer. So if they're are any examples that can be offered I'd really appreciate it.
So I took a different approach...rather than explicitly trying to display the SQL errors which have occurred, based on the scenario which took place I've written my own Exceptions messages and displayed them through the error object. This doesn't give the users too much information so it may lead to security breaches, but just enough to know the problem that has occurred.

Caught a throwable exception during processing Closed Resultset: next

So I did try checking for answers before I could ask this question again, I'm getting a closed ResultSet exception for my code below.
The same code worked on development environment when tested for a small set of records. But on QA environment the exception is encountered for 200-300 records being fetched by the query as well.
My question is, if there is no close statement or close connection code why is the closed resultset exception thrown at the While loop in the code below?
public void extractRecordsAndUpdateData() throws Throwable {
ConnectionManager mgr =null;
/*
* Some authentication code here for user authentication to allow access in the application
*/
Connection c = null;
try {
mgr = mServiceLocator.getConnectionManager();
}
catch (Exception newex) {
newex.printStackTrace();
customLogWriter.logEntry("Got a Exception during authentication " + newex.getMessage());
}
PreparedStatement pSql = null;
ResultSet myResultSet = null;
try {
c = mgr.getConnection(mgr.getSiteName());
pSql = c.prepareStatement(extractSQL); // extractSQL is a simple select statement fetching records from DB to be processed in the while loop below.
myResultSet = pSql.executeQuery();
}catch(SQLException ex){customLogWriter.logEntry("Error " + ex.getMessage());}
List<List> outerList=new ArrayList<List>();
while (myResultSet.next()) // Exception encountered on this line of code
{
/*Do some processing*/
}
customLogWriter.close();
}
Poorly structured exception handling. The ResultSet.next() loop should be inside the try block. You should only have one try and one catch (SQLException ...) here.
Don't write code like this. Code that depends on the success of code in a prior try block should be inside that try block.

SQLException, ResultSet closed but I can figure out why

I'm having a problem with java.sql.ResultSet, I have a java.sql.PreparedStatement on which I run executeQuery() to return a ResultSet yet when I try to get the results from the query I'm getting an Exception thrown:
Exception: java.sql.SQLException Message: Operation not allowed after
ResultSet closed.
From searching online it looks like a ResultSet can end up being closed for a few reason:
The PreparedStatement object that generated it is closed.
The PreparedStatement object that generated it is re-executed.
The PreparedStatement object that generated it is used to retrieve the next result from a sequence of multiple results.
Closing the Connection which was used to generate the PreparedStatement.
I checked my code and do none of those things. Below is a snippet of the code that causes the problem:
PreparedStatement psAccountPartyIdByEmail = null;
....
try {
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
String email = nextLine[0];
.....
try {
if (psAccountPartyIdByEmail == null) {
psAccountPartyIdByEmail = session.connection().prepareStatement(SQL_GET_ACCOUNTPARTYID_BY_EMAILADDRESS);
}
psAccountPartyIdByEmail.setString(1, email);
ResultSet partyIds = psAccountPartyIdByEmail.executeQuery();
while (partyIds.next()) {
String partyId = partyIds.getString(1);
.....
}
} catch (SQLException e) {
Debug.logError(e, "Encountered SQLException while running group service.", MODULE);
}
}
} catch (IOException e) {
Debug.logError(e, "Problem reading line in file", MODULE);
}
The Exception is thrown when trying to execute: while (partyIds.next()) {
Like I stated I never close the connection or statement and as you can see I don't reuse the statement prior to trying to view my result.
Thanks for he help...
Marc
I don't know if this will fix this problem but you can/should move
if (psAccountPartyIdByEmail == null) {
psAccountPartyIdByEmail = session.connection().prepareStatement(SQL_GET_ACCOUNTPARTYID_BY_EMAILADDRESS);
}
outside of the while loop.
Also, close the ResultSet after you've processed the rows.
Then, when you're all done close your statement and connection.