I'm doing something like this:
try {
client.restoreFromClusterSnapshot(req);
} catch (AmazonRedshiftException e) {
txUtils.execute((ts) -> {
redshiftDto.setStatus(ResourceStatus.FAILED);
redshiftDto.setStatusDetails(e.getMessage());
redshiftDto.setUpdatedOn(Timestamp.from(Instant.now()));
this.rdao.merge(redshiftDto);
return null;
});
LOGGER.error("CANNOT START REDSHIFT- " + e.getErrorMessage());
throw new AmazonRedshiftException( "CANNOT START REDSHIFT- "
+ e.getErrorMessage());
}
In this code, I'm not able to set database variable if I'm throwing an error because it is terminating my transaction. If I'll comment that throw it will work and my database value will be set. But I'll not able to throw anything. How can I do both- (throwing and setting value in DB)
What I'd do is make use of the finally clause.
AmazonRedshiftException exception = null;
try {
cluster = client.restoreFromClusterSnapshot(req);
} catch (AmazonRedshiftException e) {
exception = e;
LOGGER.error("CANNOT START REDSHIFT- " + e.getErrorMessage());
throw new AmazonRedshiftException( "CANNOT START REDSHIFT- "
+ e.getErrorMessage());
} finally {
if(exception != null) {
txUtils.execute((ts) -> {
redshiftDto.setStatus(ResourceStatus.FAILED);
redshiftDto.setStatusDetails(exception.getMessage());
redshiftDto.setUpdatedOn(Timestamp.from(Instant.now()));
this.rdao.merge(redshiftDto);
return null;
});
}
}
Related
sonar issue
private void getGtcj(String gtcjStatusValue, String strArchiveReqd) throws Exception {
XPathHelper activationConfigParser = null;
try {
activationConfigParser = ConfigUtil.getInstance().getConfigParser(new URL((V21Constants.FILE
+ System.getProperty(V21Constants.USER_DIR) + "/vServe21/config/ActivationParameters.xml")));
} catch (Exception e) {
log.error(e.getMessage());
}
StringBuffer useGTCJSolution = new StringBuffer();
useGTCJSolution.append(XPathConstants.ACTIVATION_CONFIG_ACTIVATION_PARAM)
.append("/parameter[#name = '").append(XPathConstants.TAG_NAME_USE_GTCJ_SOLUTION)
.append("']");
String useGTCJSolutionStr = activationConfigParser.evaluateXPath(useGTCJSolution.toString());
log.debug("useGTCJSolutionStr value:" + useGTCJSolutionStr);
if (useGTCJSolutionStr != null && useGTCJSolutionStr.trim().equalsIgnoreCase(V21Constants.YES)
&& (gtcjStatusValue.equalsIgnoreCase(Statuses.ACTIVATION_SUCCESS)
|| gtcjStatusValue.equalsIgnoreCase(Statuses.ROLLBACK_SUCCESS)
|| gtcjStatusValue.equalsIgnoreCase("Rollback Failure"))) {
log.debug("No need to archive and send response from here.");
} else {
log.debug("inside GTCJSolution for GTCJ orders...Archiving and sending response xml");
if (strArchiveReqd != null && "Yes".equalsIgnoreCase(strArchiveReqd)) {
archiveXML(responseFileName, V21Constants.VIF_ARCHIVE_RESPONSE_XML_PATH);
}
// sending the response XML
response = new Response();
response.sendResponseXML(properties, responseXml, bNBSConnectivityFlag, queueName, address);
}
}
I figured out there should be a finally block after catch, but I don't know what to add inside the finally block. Or is there any other solution?
When you create the variable activationCOnfigParser you're in a try/Catch block. You can bypass this error :
private void getGtcj(String gtcjStatusValue, String strArchiveReqd) throws Exception {
XPathHelper activationConfigParser = null;
try {
activationConfigParser = ConfigUtil.getInstance().getConfigParser(new URL((V21Constants.FILE
+ System.getProperty(V21Constants.USER_DIR) + "/vServe21/config/ActivationParameters.xml")));
} catch (Exception e) {
actionConfigParser = <DEFAULT VALUE>
log.error(e.getMessage());
}
In catch block there is that you can replace with a value that actionConfigParser has to assuming in case of exception.
I have this variable in my Constants class:
public static final String EXCEPTION_STRING= "My Exceptions message";
I want to check for it in my catch and throw a particular message if it's found. This is what I came up with:
} catch (Exception e) {
if (e.getMessage().equals(Constants.EXCEPTION_STRING)) {
throw new ServiceException(MyClassName.class.toString(),
Constants.EXCEPTION_STRING);
} else {
LOGGER.info("Save failed: " + e);
}
}
The if never seems to get entered even though I can see the correct exception message. What am I doing wrong?
Does your own custom exception get wrapped in another exception? In that case you need to do something like:
e.getCause().getMessage()
This is what I did:
} catch (Exception e) {
if (e instanceof AxisFault) {
if (e.getMessage().equals(Constants.EXCEPTION_STRING)) {
throw new ServiceException(MyClassName.class.toString(),
Constants.EXCEPTION_STRING);
}
} else {
LOGGER.info("Save failed: " + e);
}
}
I written a method which will acknowledge the controller by returning true and false, I return true inside try if everything goes fine it will return true and I return false inside catch blocks, but still method shows me error "missing return statement" what is the best way to do it.
The below method written in java will send back the true or false to the controller.
Secondly I want to carry the exception message from here to controller, I think of returning string, is it good approach,
Kindly suggest me the best way to do the exception handling
public boolean pickSalayData(String yearMonth, String regionId, String circleId, Userdetail loginUser) throws MyExceptionHandler {
String tableSuffix = yearMonth.substring(4, 6) + yearMonth.substring(0, 4);
log.info("Pick Salary Data From ERP " + DateUtility.dateToStringDDMMMYYYY(new Date()));
List<SalaryDetailReport> detailReports = hRMSPickSalaryDataDAO.findAll(yearMonth, regionId, circleId);
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus trstatus = transactionManager.getTransaction(def);
try {
List<SalaryDetailReport> salaryDetailReport = null;
int countDetail = 0;
if (detailReports != null && detailReports.size() > 0) {
for (SalaryDetailReport salary : detailReports) {
try {
if (countDetail % COMMIT_COUNT == 0) {
if (salaryDetailReport != null) {
salaryDetailReportDAO.save(salaryDetailReport, tableSuffix);
reportHistoryDAO.save(salaryDetailReport, loginUser);
}
salaryDetailReport = new ArrayList<SalaryDetailReport>();
}
salaryDetailReport.add(salary);
countDetail++;
} catch (Exception e) {
log.error("Error on Save Salary Pay Head Details Data from ERP to Prayas .");
}
}
if (salaryDetailReport != null && salaryDetailReport.size() > 0) {
salaryDetailReportDAO.save(salaryDetailReport, tableSuffix);
reportHistoryDAO.save(salaryDetailReport, loginUser);
}
} else {
throw new MyExceptionHandler("No record for Save in Database from ERP.");
}
salaryDetailReportDAO.update(tableSuffix, regionId, circleId);
List<SalaryDetailReport> reports = salaryDetailReportDAO.findAll(tableSuffix, regionId, circleId);
if (reports != null && reports.size() > 0) {
for (SalaryDetailReport salaryDetail : reports) {
try {
SalaryDetail sd = new SalaryDetail();
sd.setDetailReport(salaryDetail);
salaryDetailDAO.save(sd, tableSuffix);
} catch (Exception e) {
log.error("Error occured", e);
e.printStackTrace();
throw new MyExceptionHandler(" Error :" + e.getMessage());
}
}
System.out.println("data found");
} else {
log.error("Salary Record Not Found.");
throw new MyExceptionHandler("No record Found.");
}
salaryDetailDAO.updateEarningDeduction(tableSuffix);
//salaryDetailDAO.updateEarningDeductionsInSDT();
transactionManager.commit(trstatus);
try {
hRMSPickSalaryDataDAO.update(regionId, circleId, yearMonth);
return true;
} catch (Exception ex) {
log.error("Some error : ", ex);
}
// // System.out.println("Completed =============================");
} catch (MyExceptionHandler ex) {
transactionManager.rollback(trstatus);
ex.printStackTrace();
log.error("Failed to Save Salary data :" + ex.getMessage());
return false;
} catch (Exception ex) {
transactionManager.rollback(trstatus);
ex.printStackTrace();
log.error("Error occured on Save Salary data.", ex);
return false;
}
}
You are missing return statement for the following catch block :
catch (Exception ex) {
log.error("Some error : ", ex);
}
Either you add return statement in this catch block or at the end of mehtod
If this code throws an Exception, then the following catch code will not be entered into and hence there is no return value
try {
hRMSPickSalaryDataDAO.update(regionId, circleId, yearMonth);
return true;
} catch (Exception ex) {
log.error("Some error : ", ex);
**edit**
return `true||false`;
}
} catch (...) {
return something;
}
I have a very curious situation.
I'm trying to execute EJB's method and returns the result with JAX-RS
public Service readSingle(...) {
try {
service.query(...);
} catch (final NoResultException nre) {
throw new NotFoundException(...);
} catch (final NonUniqueResultException nure) {
throw new BadRequstException(...);
}
}
The query method requires some values and a BiFuction and a Function.
The actual call looks like this.
try {
return serviceService.<Service>query(
id,
ofNullable(matrixParameters.getFirst("onid"))
.map(Integer::parseInt).orElse(null),
ofNullable(matrixParameters.getFirst("tsid"))
.map(Integer::parseInt).orElse(null),
ofNullable(matrixParameters.getFirst("sid"))
.map(Integer::parseInt).orElse(null),
ofNullable(matrixParameters.getFirst("number"))
.map(Integer::parseInt).orElse(null),
ofNullable(matrixParameters.getFirst("programId"))
.orElse(null),
operatorId,
(builder, root) -> emptyList(),
TypedQuery::getSingleResult);
} catch (final NoResultException nre) {
throw new NotFoundException(
"no entity idnetified by " + serviceIdSegment.getPath()
+ " with " + matrixParameters.toString());
} catch (final NonUniqueResultException nure) {
throw new BadRequestException("multiple entities identified");
}
Ok I passed TypedQuery::getSingleResult and I expect NonUniqueResultException should be caught when it has to be thrown.
But Payara keep responding with 500 and the log shows that the NonUniqueResultException has never caught by the code.
I disabled my ExceptionMappers the the results are same.
Ok. I figured it out. I had to do this.
try {
// execute EJB
} catch (final EJBTransactionRolledbackException ejbtre) {
Exception leaf = ejbtre;
try {
for (Exception c;
(c = ((EJBException) leaf).getCausedByException()) != null;
leaf = c);
} catch (final ClassCastException cce) {
}
logger.severe("causedByException: " + leaf);
if (leaf instanceof NoResultException) {
throw new NotFoundException(
"no entity idnetified by " + serviceIdSegment.getPath()
+ " with " + matrixParameters.toString());
} else if (leaf instanceof NonUniqueResultException) {
throw new BadRequestException(
"multiple entities identified by "
+ serviceIdSegment.getPath()
+ " with " + matrixParameters.toString());
}
throw new InternalServerErrorException(ejbtre);
}
This is far nasty beyond I've expected. The EJB's method design is not good.
Is there any way to do this more simply?
Let me introduce one of my utility class I used to justify myself.
public final class EJBExceptions {
private static final Logger logger
= getLogger(EJBExceptions.class.getName());
public static Stream<Exception> causedByExceptions(EJBException ejbe) {
final Stream.Builder<Exception> builder = Stream.builder();
while (ejbe != null) {
final Exception causedByException = ejbe.getCausedByException();
if (causedByException != null) {
builder.add(causedByException);
} else {
break;
}
if (causedByException instanceof EJBException) {
ejbe = (EJBException) causedByException;
} else {
break;
}
}
return builder.build();
}
public static Optional<Exception> lastCausedByException(
final EJBException ejbe) {
return causedByExceptions(ejbe).reduce((first, second) -> second);
}
private EJBExceptions() {
super();
}
}
I'd like to know how I could throw a "final" Exception, containing a detailed message with all the detailed messages of a number of chained exceptions.
For example suppose a code like this:
try {
try {
try {
try {
//Some error here
} catch (Exception e) {
throw new Exception("FIRST EXCEPTION", e);
}
} catch (Exception e) {
throw new Exception("SECOND EXCEPTION", e);
}
} catch (Exception e) {
throw new Exception("THIRD EXCEPTION", e);
}
} catch (Exception e) {
String allMessages = //all the messages
throw new Exception(allMessages, e);
}
I'm not interested in the full stackTrace, but only in the messages, I wrote. I mean, I'd like to have a result like this:
java.lang.Exception: THIRD EXCEPTION + SECOND EXCEPTION + FIRST EXCEPTION
I think what you need is:
public static List<String> getExceptionMessageChain(Throwable throwable) {
List<String> result = new ArrayList<String>();
while (throwable != null) {
result.add(throwable.getMessage());
throwable = throwable.getCause();
}
return result; //["THIRD EXCEPTION", "SECOND EXCEPTION", "FIRST EXCEPTION"]
}
you can better use it this way, merge the message() of previous Exception with the message() of new Exception you are throwing:
} catch (Exception e) {
throw new Exception("FIRST EXCEPTION" + e.getMessage(), e);
}
Cycle through the exception cause and append the message in each exception.
try
{
try
{
try
{
try
{
throw new RuntimeException("Message");
}
catch (Exception e)
{
throw new Exception("FIRST EXCEPTION", e);
}
}
catch (Exception e)
{
throw new Exception("SECOND EXCEPTION", e);
}
}
catch (Exception e)
{
throw new Exception("THIRD EXCEPTION", e);
}
}
catch (Exception e)
{
String message = e.getMessage();
Throwable inner = null;
Throwable root = e;
while ((inner = root.getCause()) != null)
{
message += " " + inner.getMessage();
root = inner;
}
System.out.println(message);
}
Which prints
THIRD EXCEPTION SECOND EXCEPTION FIRST EXCEPTION Message
You can just add the previous exception message on each exception
This is an example :
public static void main(String[] args) {
try {
try {
try {
try {
throw new Exception();
// Some error here
} catch (Exception e) {
throw new Exception("FIRST EXCEPTION", e);
}
} catch (Exception e) {
Exception e2 = new Exception("SECOND EXCEPTION + " + e.getMessage());
throw e2;
}
} catch (Exception e) {
Exception e3 = new Exception("THIRD EXCEPTION + " + e.getMessage());
throw e3;
}
} catch (Exception e) {
System.out.println(e);
}
}
The result is : java.lang.Exception: THIRD EXCEPTION + SECOND EXCEPTION + FIRST EXCEPTION
Here is a nice utility for converting chained exceptions to string:
public final class ThrowableUtil {
private ThrowableUtil() {}
public static String chainedString(#NonNull Throwable throwable) {
StringBuilder SB = new StringBuilder(throwable.toString());
while((throwable = throwable.getCause()) != null)
SB.append("\ncaused by ").append(throwable);
return SB.toString();
}
public static String chainedString(#NonNull String msg, #NonNull Throwable throwable) {
StringBuilder SB = new StringBuilder(msg);
do {
SB.append("\ncaused by ").append(throwable);
} while((throwable = throwable.getCause()) != null);
return SB.toString();
}
}
Example output:
ThrowableUtil.chainedString(e);
produces
java.io.IOException: Failed to create required video encoder
caused by java.lang.RuntimeException: Invalid mime type
Another example output:
ThrowableUtil.chainedString("Writing of media file failed", e);
produces
Writing of media file failed
caused by java.io.IOException: Failed to create required video encoder
caused by java.lang.RuntimeException: Invalid mime type
I had saved all attributes in a class object with the following example:
public List<ErrorMessage> getMessageList(Throwable throwable) {
List<ErrorMessage> errorMessageList = new ArrayList<ErrorMessage>();
while (throwable != null) {
ErrorMessage message = new ErrorMessage();
message.set_message( throwable.getMessage());
message.set_line(throwable.getStackTrace()[0].getLineNumber());
message.set_methodName(throwable.getStackTrace()[0].getMethodName());
message.set_fileName(throwable.getStackTrace()[0].getFileName() );
message.set_className(throwable.getStackTrace()[0].getClassName());
errorMessageList.add(message);
throwable = throwable.getCause();
}
return errorMessageList;
}
Maybe simpler
try {
// code that throws exception
} catch(Throwable e ) {
var messages = new ArrayList<String>();
do {
messages.add(e.getMessage());
e = e.getCause();
} while( e!= null );
var message = String.join(" -> ", messages);
System.out.println(message);
}