Comparison of exception message always fails in if my statement - java

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);
}
}

Related

How to get Exception Class from Exception Name

I have a string variable that has a full qualified exception name. I want to check in catch block if exceptions occur whether it is an instance of exception that mentioned in string or not. How to solve that
String stringEx = "org.hibernate.StaleStateException";
try {
// program
} catch (Exception ex) {
if (e instanceof stringEx) { //<-- How to convert string to exception class
// do specific process
}
}
Maybe you need this:
String stringEx = "org.hibernate.StaleStateException";
try {
// program
} catch (Exception ex) {
if (Class.forName(stringEx).isInstance(ex)) {
// do specific process
}
}

How to throw an error with transaction java

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;
});
}
}

How to make TestNG continue test execution on an exception?

When i get an exception, the test run immediately ends, and any following test validations are skipped. I would like to catch the exception, handle it, then continue the workflow.
In the below example, If objPage.Method1(); throws an exception, the entire #Test immediately ends. I would like the catch to execute, then move on to objPage.Method2().
#Test (enabled=true)
public void MyClientsFunctions() throws Exception {
ExtentTest t = ReportFactory.getTest();
try {
Login objPage = new PageObject(driver);
//this method throws exception
objPage.Method1();
if (x=y)
t.log(LogStatus.PASS, "Pass message");
else
t.log(LogStatus.FAIL,"Fail message"+ screenshotMethod());
objPage.Method2();
if (a=b)
t.log(LogStatus.PASS, "Pass message");
else
t.log(LogStatus.FAIL,"Fail message"+ screenshotMethod());
} catch (Exception e) {
t.log(LogStatus.ERROR, "Exception found: " + e.getMessage() + screenshotMethod());
}
}
I am using PageFactory and ExtentReports. I am use if statements to report failures. No asserts. I believe if an assert fails, the result is the same, and the test ends.
Write the objPage.Method2() in final block then it will execute.
Credit to #JeffC for pointing me in the right direction.
For my case, I have at least a dozen action methods called from the Page Object class. I can't put them all in their own final block.
What I did was put each workflow (one or more methods, then validation) in it's own try/catch. The catch includes logging/screenshot, then redirects to the page that the next workflow needs to execute. So, we try/catch(login), try/catch(enterHoursWorked) etc... As others have said, it's ugly, but in my case it works. Now the exception is added to the log, and the next workflow executes
public void MyClientsFunctions() throws Exception {
ExtentTest t = ReportFactory.getTest();
try {
Login objPage = new PageObject(driver);
// this method throws exception
try {
objPage.Login();
if (x = y)
t.log(LogStatus.PASS, "Pass message");
else
t.log(LogStatus.FAIL, "Fail message" + screenshotMethod());
} catch (Exception e) {
t.log(LogStatus.ERROR, "Exception found: " + e.getMessage() + screenshotMethod());
objPage.BackToHomePage();
}
try {
objPage.EnterHoursWorked();
if (a = b)
t.log(LogStatus.PASS, "Pass message");
else
t.log(LogStatus.FAIL, "Fail message" + screenshotMethod());
} catch (Exception e) {
t.log(LogStatus.ERROR, "Exception found: " + e.getMessage() + screenshotMethod());
objPage.BackToHomePage();
}
} catch (Exception e) {
t.log(LogStatus.ERROR, "Exception found: " + e.getMessage() + screenshotMethod());
}
}

Java exception handling get console error message

I want to get error message using java when exception are generated.
now I have java code with following scenario:
method first(){
try{
second();
}catch(Exception e){
System.out.println("Error:> "+e)
}
}
method second(){
try{
my code
}catch(Exception e){
throw new Exception("Exception generate in second method",e);
}
}
now when the first method execute then I get only "Exception generate in second method" message but there is some other message printed on console by java so how to get that console error message.
Note: I have already try with e.getMessage(); and e.printStackTrace();
Every exception has a cause that you can get with getCause(). You can go recursively down them until you get to the root cause. Here is your example with a utility that dumps the exception with all its causes like the console does.
private void first() {
try {
second();
} catch (Exception ex) {
Log.e("CATCH", getExceptionDump(ex));
}
}
private void second() {
try {
throw new UnsupportedOperationException("We don't do this.");
} catch (Exception ex) {
throw new RuntimeException("Exception in second()", ex);
}
}
private String getExceptionDump(Exception ex) {
StringBuilder result = new StringBuilder();
for (Throwable cause = ex; cause != null; cause = cause.getCause()) {
if (result.length() > 0)
result.append("Caused by: ");
result.append(cause.getClass().getName());
result.append(": ");
result.append(cause.getMessage());
result.append("\n");
for (StackTraceElement element: cause.getStackTrace()) {
result.append("\tat ");
result.append(element.getMethodName());
result.append("(");
result.append(element.getFileName());
result.append(":");
result.append(element.getLineNumber());
result.append(")\n");
}
}
return result.toString();
}
The message in the Exception constructor argument is not printed in the exception detail.
You can simply use this code to print the message :
method first(){
try{
second();
}catch(Exception e){
System.out.println("Error:> "+e.getMessage())
}
}
Hope this solves your problem
Why you cannot use print stack trace ?
Because A throwable contains a snapshot of the execution stack of its thread at the time it was created. (see Throwable)
It implies that, if you want to print the stack trace you need to use the printStackTrace() method BUT in your second method !
method second(){
try {
my code
} catch(Exception e) {
e.printStackTrace();
throw new Exception("Exception generate in second method",e);
}
}
Or using a the tricky method setStackTrace and using the printStackTrace() in first
method second(){
try {
my code
} catch(Exception e) {
Exception ex = new Exception("Exception generate in second method",e);
ex.setStackTrace(e);
throw ex;
}
}
method first(){
try {
second();
} catch(Exception e) {
e.printStackTrace();
}
}
You can print the cause of the exception you get. Try this:
method first(){
try{
second();
}catch(Exception e){
System.out.println("Error:> "+e);
if (e.getCause() != null) {
System.out.println("Cause:> " + e.getCause());
}
}
}
I believe this is the console message you want to achieve:
Error:> java.lang.Exception: Exception generate in second method
Try this code, when the catch block of the second method throws an exception the second method should declare it as throws or put a nested try catch within the catch block.
The exception is propagated to the first() method which is handled by its catch block.
public class Test {
public void first() {
try {
second();
} catch (Exception e) {
System.out.println("Error:> " + e);
}
}
public void second() throws Exception {
try {
throw new Exception();
} catch (Exception e) {
throw new Exception("Exception generate in second method", e);
}
}
public static void main(String ars[]) {
Test test = new Test();
test.first();
}
}

Get detail messages of chained exceptions Java

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);
}

Categories

Resources