Duplicate Key Exception from Mongo DB does not gets caught - spring-data-mongodb-reactive

Trying to insert duplicate documents in mongo db with help of mongo repository.
Snippet example:
try{ //insertion of duplicate doc in mongo db } catch(org.springframework.dao.DuplicateKeyException e){ // syso for something else for sake of this example }
I can see the exception getting thrown in console like errorMsg": "E11000 duplicate key error collection
But in code its not coming to catch block at all.
Why this exception cannot be caught in catch block?
Tried catching this exception with all the below exception instances:
org.springframework.dao.DuplicateKeyException,
com.mongodb.MongoWriteException,
Exception.
Since the exception is getting thrown and its evident from the logs it should be caught in catch block.

Related

JDBCtemplate doesn't allow catch SQLException

I'm using Spring JDBC and I've got this test method to connect to PostgreSQL DB (It's a example code, this isn't the original code):
public void toConnect() {
final String sql = "SELECT 1";
template.execute(sql);
}
If I catch the DataAccessException, and I call method getCause() the program trigger the PLSQException anyway (though finally printing the message that I set in the catch).
public void toConnect() throws CGConnException {
final String sql = "SELECT 1";
try {
template.execute(sql);
} catch (DataAccessException e) {
throw new CGConnException("CG : Error DataBase connection. - ", e.getCause());
}
}
The problem is than I can't handle the exception and I want than only print the Message of the catch, without the exception details.
If it's run with an error on config parameters or the PostgreSQL database is down, a PSQLException is generated and that is great but I need to control this exception. However JdbcTemplate.execute(sql) method throws a DataAccessException, therefore, doesn't possibly catch the PSQLException on try/catch block (or I don't know how to do). So, when run the program always appears the stack trace in the console:
2021-05-02 03:10:14.052 ERROR 73837 --- [ main] .PostgresClientTestConnectionApplication : Error : CG : Error DataBase connection.
In this case, I need to print only a log as "Connection Error" or something similar as the example above.
Thank you in advance.
Actually there is no mistake. The exception is handled and the program finally correctly when is catch it.
try {
template.execute(sql);
logger.error("Connection Successful . . .");
} catch (Exception e) {
logger.error("Error connection" + e.getMessage());
throw new CGConnException("CG : Error DataBase connection. - ", e);
}
In the run console it's print the associate stack trace because Spring internal classes to do it, but don't mean than we are doing something wrong or than no handle the exception.

Provide Error Description When Error Occurs in Spring Boot

I m Trying to get Error Code And Error Description whenever Error is thrown From Try Block and as well as Error Class Name.
Whenever is error is thrown from try block i m getting Exception Class Name But I m not getting Exact Description why Error is occuring i need Description.
catch (Exception e) {
System.out.println("########################
e.getMessage()"+e.getMessage());
System.out.println("*******************************
e.getLocalizedMessage()"+e.getLocalizedMessage());
System.out.println("########################## e.getCause()
"+e.getCause());
System.out.println("************************** e.getClass()
"+e.getClass().getConstructors());
System.out.println("************************** e.getClass()
"+e.getClass().getName());
}
I want The Error Description why Error is Producing like if
DataIntegrityViolationException occurs i need on which constraint it just giving DataIntegrityViolationException error.

Identifying database errors and query errors separate in spring

I am writing a RESTful web service using spring 3 and I noticed that when I implemented my DAO's (I am using spring-jdbc for database access), the exceptions that get thrown are pretty generic, so i am not able to identify if the exception occurred because my database is down or my query failed.
sample code:
try {
Q q = jdbcTemplate.queryForObject(MY_QUERY, new Object[]{id}, new MyMapper());
return q;
} catch (DataAccessException e) {
// What is this exception ? database down ? query failed ?
}
Unless I know what exception is this during runtime, I can't send back reasonable error message to service client.
Any help is appreciated. Thanks
You shouldn't be trying to catch every single possible exception; code so that you don't run into the possibility of multiple user or programmer error type exceptions. Generally there are three type of exceptions that occur in every DAO regardless of what you do. (1) your database is down... imo if this is the issue you've got bigger problems. (2) user authentication error which is easy enough to catch and deal with (however you should probably be handling that situation on your RESTful front-end. (3) improper data. If you have bad data, just send the attempted data back and the reason for the exception.
try {
Q q = jdbcTemplate.queryForObject(MY_QUERY, new Object[]{id}, new MyMapper());
return q;
} catch (DataAccessException e) {
throw new DaoException("Could not retrieve q with ID: " + qID, e);
}
The method queryForObject only throws DataAccessException or IncorrectResultSizeDataAccessException. You shouldn't catch exception due to database connection failure at this level. However, in your DAO class, you normally have code to establish the dataSource which can be injected by Spring's IoC container. That part of code will throw exception if the database connection fails. You should catch DB failure exception there.

How to catch PSQLException value too long for type character varying

I'm currently testing the data access layer that I've created in spring (PersistenceContext is injected). So I have a stateless EJB that calls a service for example UserService, that inserts/delete/update data in the database.
The service works fine, I was able to insert database. But when I was testing and I input string value that is longer than the set length I got:
javax.transaction.RollbackException: Transaction marked for rollback.
WARNING: DTX5014: Caught exception in beforeCompletion() callback:
javax.persistence.PersistenceException: org.hibernate.exception.DataException: ERROR: value too long for type character varying(20)
Caused by: org.hibernate.exception.DataException: ERROR: value too long for type character varying(20)
Caused by: org.hibernate.exception.DataException: ERROR: value too long for type character varying(20)
My partial code:
#PersistenceContext
protected EntityManager entityManager;
try {
entityManager.persist(e);
} catch(Exception e) {
//log message here
}
Then I've tried everything to catch these errors but I was not able to. Any suggestion on how to resolve the issue?
Thanks,
czetsuya
I've used the following code to find out which error is thrown under your circumstances:
BEGIN;
CREATE TABLE t(v varchar(5));
DO $body$
BEGIN
INSERT INTO t VALUES ('1234567');
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE '!!! %, %', SQLSTATE, SQLERRM;
END;$body$;
ROLLBACK;
You'll see, that error code is 22001, error is named string_data_right_truncation per PostrgeSQL's list of error codes.
I don't know how to catch this error in the Hibernate, but on the PL/pgSQL level you can do it using:
EXCEPTION WHEN SQLSTATE '22001' THEN
-- your code follows
END;
I hope this will help you.

About Spring Transaction Manager

Currently i am using spring declarative transaction manager in my application. During DB operations if any constraint violated i want to check the error code against the database. i mean i want to run one select query after the exception happened. So i am catching the DataIntegrityViolationException inside my Catch block and then i am trying to execute one more error code query. But that query is not get executed . I am assuming since i am using the transaction manager if any exception happened the next query is not getting executed. Is that right?. i want to execute that error code query before i am returning the results to the client. Any way to do this?
#Override
#Transactional
public LineOfBusinessResponse create(
CreateLineOfBusiness createLineOfBusiness)
throws GenericUpcException {
logger.info("Start of createLineOfBusinessEntity()");
LineOfBusinessEntity lineOfBusinessEntity =
setLineOfBusinessEntityProperties(createLineOfBusiness);
try {
lineOfBusinessDao.create(lineOfBusinessEntity);
return setUpcLineOfBusinessResponseProperties(lineOfBusinessEntity);
}
// Some db constraints is failed
catch (DataIntegrityViolationException dav) {
String errorMessage =
errorCodesBd.findErrorCodeByErrorMessage(dav.getMessage());
throw new GenericUpcException(errorMessage);
}
// General Exceptions handling
catch (Exception exc) {
logger.debug("<<<<Coming inside General >>>>");
System.out.print("<<<<Coming inside General >>>>");
throw new GenericUpcException(exc.getMessage());
}
}
public String findErrorCodeByErrorMessage(String errorMessage)throws GenericUpcException {
try{
int first=errorMessage.indexOf("[",errorMessage.indexOf("constraint"));
int last=errorMessage.indexOf("]",first);
String errorCode=errorMessage.substring(first+1, last);
//return errorCodesDao.find(errorCode);
return errorCode;
}
catch(Exception e)
{
throw new GenericUpcException(e.getMessage());
}
}
Please help me.
I don't think problem you're describing has anything to do with Transaction management. If DataIntegrityViolationException happens within your try() block you code within catch() should execute. Perhaps exception different from DataIntegrityViolationException happens or your findErrorCodeByErrorMessage() throwing another exception. In general, Transaction logic would be applied only once you return from your method call, until then you could do whatever you like using normal Java language constructs. I suggest you put breakpoint in your error error handler or some debug statements to see what's actually happening.

Resources