Struts2 Exception handling usage? - java

I have my Action class below in which getTspNameIdMap throws ReqMgmtException exception (custom exception).
public String findTspNameIdMap(){
SlsReqMgmtCommonRemote slsReqMgmtCommonRemote = null;
tspNameIdMap = new HashMap<String, String>();
try{
slsReqMgmtCommonRemote = getSlsReqMgmtCommonRemote();
tspNameIdMap = slsReqMgmtCommonRemote.getTspNameIdMap(gmaThresholdParameters.getId().getCircleId());
}
catch(ReqMgmtException rEx){
addActionError(rEx.getError());
result = "error";
return ERROR;
}
catch (Exception e){
addActionError("Error in processing your request. Contact Administrator");
e.printStackTrace();
System.out.println("[ConfigureTspThresholdAction: findTspNameIdMap Function]:In catch Inside Constructor!!");
result = "error";
return ERROR;
}
return SUCCESS;
}
I know there is exception handling in Struts2 too, however presently I am not using it.
Should I use Struts2 exception handling? What would be its usage?

You should use exception handling mechanism in Struts2, that's what exception interceptor provides. Also you should handle exceptions in the action method like in your question. If it handles all exceptions good, if not the exception handler could handle it. Also in some methods which doesn't have throws Exception signature you can only catch the exception but cannot return ERROR result. So, rethrowing the exception and handling it by the interceptor is the workaround.
References:
Exception handling in struts2 and hibernate
Which Exceptions to declare/handle in struts xml
Struts 2 what to do when user inserts action which does not exist
how to validate json being sent using struts2 json plugin without throwing exception

Related

#ControllerAdvice doesn't handle more specific exception

There's a piece of code that throws a exception:
java.lang.RuntimeException: cn.dev33.satoken.exception.NotLoginException: Invalid Token:ldxutBDDKBEDa9LjWNTKLFbW7g7B86qU.
And then it goes into handleRuntimeException rather than returnNotLoginException method.
#Component
#Slf4j
#Primary
public class MyLockKeyBuilder extends DefaultLockKeyBuilder {
#Override
public String buildKey(MethodInvocation invocation, String[] definitionKeys) {
String key = super.buildKey(invocation, definitionKeys);
Object loginId = StpUtil.getLoginId(); // throw a exception
key = loginId.toString();
return key;
}
}
#ControllerAdvice(basePackages = "com.test")
#Slf4j
public class GraceExceptionHandlerApp {
#ResponseStatus(HttpStatus.UNAUTHORIZED)
#ExceptionHandler(value = NotLoginException.class)
#ResponseBody
public JSONObject returnNotLoginException(NotLoginException e) {
e.printStackTrace();
String message = e.getMessage();
ResponseStatusEnum failed = ResponseStatusEnum.UNAUTHORIZED;
failed.setMsg(message);
return ZheliResult.exception(failed);
}
#ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
#ExceptionHandler(RuntimeException.class)
#ResponseBody
public JSONObject handleRuntimeException(RuntimeException e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
return ZheliResult.errorCustom(ResponseStatusEnum.FAILED);
}
...
}
I want it goes into the returnNotLoginException method, could anyone tell me how to do it?
UPDATE
I've made a mistake, really, for I didn't offer enough info.
Missed Info:
My application was a distributed system and services to invoke another via rpc communication. MyLockKeyBuilder was on the provider service, and GraceExceptionHandlerApp was on the comsumer service.
When the provider service throw a exception and before it being passed to the comsumer sevice, it would be filter by a Filter called ExceptionFilter, which wrap the exception that the comsumer side doesn't recognize to RuntimeException, to avoid serialization issue.
Finally I solved this problem by rewritting the ExceptionFilter class to allow original NotLoginException to be passed to the consumer side.
NotLoginException is the inner exception of your RuntimeException. If you want your controller advice to handle it, catch the RuntimeException buildKey and throw its inner exception.
Based on your question,
java.lang.RuntimeException: cn.dev33.satoken.exception.NotLoginException: Invalid Token:
Your exception type is java.lang.RuntimeException & cause of exception is NotLoginException.
Controller advice will invoke respective method when type of exception matches & not cause of exception.
So if you really want to invoke returnNotLoginException, then you need to throw NotLoginException in your logic instead of throwing RuntimeException.
Something like:
..
throw new NotLoginException("exception"); //in your StpUtil.getLoginId();
..

Throwing a custom exception instead of other types of exceptions

I have a program in which I want to throw one of 4 exceptions that I define.
I get an HTTP response and according its error code I want to throw the exceptions:
Here is an example:
public List<Map<String, Object>> getData(String product) {
try {
Response<DataGeneralResponse> response = dataApi.dataGet(product).execute();
if (!response.isSuccessful()) {
log.error(String.format("Failed to get data for product [%s] error [%s]",
product,
Util.getErrorMsg(response)));
}
DataGeneralResponse body = response.body();
return body != null ? body.getData(): null;
} catch (Exception e) {
log.error(String.format("Failed to get data for product [%s] error[%s]",
product,
Util.getErrorMsg(response)));
}
return null;
}
So I need to to something like that in Util:
public void handleResponse(Response<DataGeneralResponse> response) throws CustomException {
switch (response.code()) {
case 500: throw new FirstCustomException(");
break;
case 404: throw new SecondCustomException(");
break;
default: throw new UnknownCustomException(");
}
}
But when I try to remove the catch clause I get unhandled IOException error on the execute method and on the getErrorMsg method.
Can someone help please?
I get unhandled IOException error on the execute method and on the getErrorMsg method.
This indicates that you have a method, which is trying to throw a checked exception, which is not surrounded by a try catch clause. By Java language standard all methods, which throw checked exceptions must do one of the two ..
Be surrounded by a try-catch block which catches the relevant exception
Declare that they throw the relevant exception by using the throws keyword
You can use one of the methods above to deal with error you are getting.
If this does not completely solve your problem, please add a comment below and I'll respond.

Java - How to catch all exceptions/errors from xml validating file

I woudlike to get all errors from my validating xml. Actually my method stop after catch the first error :
public List<String> validation(File file) {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
List<String> statut = new ArrayList<>();
try {
assert xsd != null;
Schema schema = schemaFactory.newSchema(xsd);
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new File(file.getPath() + file.getname())));
statut.add(file.getname() + " is valid");
} catch (SAXException | IOException e) {
statut.add(file.getname() + " not valid :\n");
statut.add(e.getMessage());
}
return statut;
}
How can I get all exception detected ?
You can use Validator.setErrorHandler(ErrorHandler) to register your own error handler.
public abstract void setErrorHandler(ErrorHandler errorHandler)
Sets the ErrorHandler to receive errors encountered during the validate method invocation.
Error handler can be used to customize the error handling process during a validation. When an ErrorHandler is set, errors found during the validation will be first sent to the ErrorHandler.
The error handler can abort further validation immediately by throwing SAXException from the handler. Or for example it can print an error to the screen and try to continue the validation by returning normally from the ErrorHandler
If any Throwable is thrown from an ErrorHandler, the caller of the validate method will be thrown the same Throwable object.
Validator is not allowed to throw SAXException without first reporting it to ErrorHandler.
In your own error handler, you can aggregate the exceptions and then after validation, process as needed/wanted.
Specifically, it allows you to continue validation if errors are encountered enabling you to catch them all in the handler.

How to capture the mybatis exception "org.apache.ibatis.exceptions.PersistenceException"?

Here is the code sample, I want to capture the exception throwed by mybatis:
String resource = "com/sureone/server/db/mybatis-config.xml";
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
sqlSession = factory.openSession(true);
tUserMapper = sqlSession.getMapper(TUserMapper.class);
if(tUserMapper.insert(user)>0){ <===Exception throwed here for duplicate entry problem
return verifyLogin(user.getAccount(),user.getPassword());
}
return null;
The exception I want to captured:
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'userName' for key 'account_UNIQUE'
You can capture the PersistenceException as you would do usually :
try {
...
} catch (PersistenceException pe) {
}
But don't forget that this Exception wraps the real one:
From MyBatis code
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e);
}
So if you would like the get a grip on the cause of the PersistenceException you'll have to use .getCause() method on the PersistenceException
Be aware that MyBatis can also launch its own PersistenceException (TooManyResultException,BindingException ...) classes, those won't have a cause Exception wrapped.
You can capture the ibatis exception by adding a try/catch block around your statements that invoke myBatis query/insert. For instance, if you use the SqlSessionTemplate and the selectList() method, you can do this:
try {
myResults = mySqlSessionTemplate.selectList("getInfoList", parameterMap);
} catch (final org.apache.ibatis.exceptions.PersistenceException ex) {
logger.error("Problem accessing database");
throw ex;
}
Whether you re-throw the exception or consume and deal with it here is your choice. However, beware of "eating" it and not dealing with the problem, since this will allow calling code to progress without knowing about the underlying data access problem.

Spring MVC Handling dao.EmptyResultDataAccessException

I would like to know whats the best way to handle org.springframework.dao.EmptyResultDataAccessException in my application.
This error occurs when I try to select records from the database that doesn't exist.
Exceptions(data related) caught in DAO layer should not be passed in Service layer. You would handle all exceptions in dao layer and rethrow them with your custom exceptions like :
public class SomeDaoImpl implements SomeDaoInterface {
public void someDaoMethod() throws Exception {
// code ...
try {
// code
} catch(EmptyResultDataAccessException dataAccessException) {
// rethrow exception
throw new Exception(dataAccessException.toString()); // you can rethrow RuntimeException or Custom exceptions
}
}
}

Categories

Resources