Java- Issue with try-catch exception inside custom exception - java

I have a custom Java exception class, CustomRestException:
import org.codehaus.jettison.json.JSONObject;
public class CustomRestException extends Exception{
private String httpStatusMessage;
private Integer httpStatusCode;
private String endpointBody;
private String callType;
private List<HashMap<String,String>> headerParams;
private List<HashMap<String,String>> queryParams;
private JSONObject endPointErrorResponse;
public CustomRestException (RestCallParameters p,String type,String url,String body,UniformInterfaceException ue) {
super(p.getCollectionErrMsg());
this.endpointBody= body;
this.endPointUrl = url;
this.callType = type;
setUniformInterfaceExceptionParameters(ue);
}
private void setUniformInterfaceExceptionParameters(UniformInterfaceException ue) {
try {
this.httpStatusMessage = ue.getMessage();
this.httpStatusMessage = ue.getResponse().getClientResponseStatus().toString();
this.httpStatusCode = ue.getResponse().getStatus();
this.endPointErrorResponse =
new JSONObject(ue.getResponse().getEntity(String.class));
}
catch (Exception ex) {
LOGGER.info("[setUniformInterfaceExceptionParameters] Ecnountered error ",ex);
}
}
}
I am throwing this CustomRestException from a method:
public String myMethod() throws CustomRestException {
try{
//make some rest call here
}catch(UniformInterfaceException ue){
throw new CustomRestException (p,"POST",url,p.getReqBody(),ue);
}
}
then, I am catching this CustomRestException somewhere else:
public Response myEndPointMethod(){
try{
//some code
myClassObj.myMethod(); //calling myMethod() above
//some code
} catch (CustomRestException e) {
LOGGER.error("(someMessage) CustomRestException ", e);
}
My problem
this.endPointErrorResponse = new JSONObject(ue.getResponse().getEntity(String.class));
If this line throws any exception (I have seen only JSONException so far), the program terminates after executing this logger in the catch block:
LOGGER.info("[setUniformInterfaceExceptionParameters] Ecnountered error ",ex);
My Expectation
The logger LOGGER.error("(someMessage) CustomRestException ", e); in myEndPointMethod() should be called.
Are we not supposed to handle (try-catch) exceptions inside custom exceptions?
Any idea where I am going wrong?

Related

Mockito to test the catch block of private method

I need to write a test to verify that when an IOException is thrown by the private method_C, Method_B returns True.
But
public final class A{
public static Boolean Method_B(){
try{
//call a private method C which throws IOException
Method_C
}
catch(final IOException e) {
return Boolean.True
}
}
private static Method_C() throws IOException {
return something;
}
What I tried:
#Test
public void testSomeExceptionOccured() throws IOException {
A Amock = mock(A.class);
doThrow(IOException.class).when(Amock.Method_C(any(),any(),any(),any()));
Boolean x = A.Method_B(some_inputs);
Assert.assertEquals(Boolean.TRUE, x);
}
I am getting compilation errors :
1.Cannot mock a final class
2. Method_C has private access in A
Any suggestions on how this can be rectified?
you are required to use finally in try catch
import java.io.*;
public class Test {
public static Boolean Method_B() {
try {
System.out.println("Main working going..");
File file = new File("./nofile.txt");
FileInputStream fis = new FileInputStream(file);
} catch (IOException e) {
// Exceptiona handling
System.out.println("No file found ");
} catch (Exception e) {
// Exceptiona handling
System.out.println(e);
} finally {
return true;
}
}
public static void main(String args[]) {
if (Test.Method_B()) {
System.out.println("Show true ans");
} else {
System.out.println("Sorry error occure");
}
}
}

How to get specific error instead of Internal Server Error?

I am getting Internal Server Error on postman even though I am throwing a custom exception from my code exception.
I want to see the exception of having a valid error message and error code, what I am throwing. It will be a great help if anyone of you can help me on this point. Like how I can get a better error message. Adding below code snap.
Thanks in advance.
#Service
public class FetchActionImpl implements FetchAction {
private static Logger log = LoggerFactory.getLogger(FetchActionImpl.class);
#Autowired
FetchActionServiceImpl fetchActionService;// = new FetchActionServiceImpl();
#Override
public FetchResponse fetchActionRequest(String caseId) throws BBWException,Exception{
//String resp ="";
log.info("fetchaction Request: {}",ApplicationConstants.LOG_ENTRY_MESSAGE);
log.info("The caseId received from BRASS:\n {}",caseId);
FetchResponse resp = null;
try{
if(true) {
throw new BBWException("500","Test");
}
resp = fetchActionService.fetchIt(caseId);
log.debug("fetchaction Response: {}",resp.toString());
}
catch (BBWException be) {
throw be;
}
catch (Exception e) {
throw new BBWException("500",e.getMessage());
}
return resp;
}
}
#Api
#Path("/fetch_service")
public interface FetchAction {
#GET
#Path("/fetchaction/caseid/{caseid}")
#Produces({MediaType.APPLICATION_JSON})
//#Consumes({MediaType.TEXT_XML})
#ApiOperation(
value = "Respond BRASS Request",
notes = "Returns a XML object "
)
#ApiResponses(
value = {
#ApiResponse(code = 404, message = "Service not available"),
#ApiResponse(code = 500, message = "Unexpected Runtime error")
})
public FetchResponse fetchActionRequest(#PathParam("caseid") String caseid) throws BBWException, Exception;
}`
public class BBWException extends Exception {
private static final long serialVersionUID = -7987978270260338068L;
private String errorCode;
private String errorMessage;
public BBWException(String errorCode, String errorMessage) {
super(errorMessage);
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
#Override
public String toString() {
return (this.errorCode + " " + this.errorMessage);
}
}
Each time the (uncaught) exception is thrown, SpringBoot returns Http-500 Internal Server Error. There are many ways of handling exceptions in Spring.
Let's say I have my controller and I implicitly throw an exception.
#RestController
public class HelloWorldController {
#GetMapping("/hello-world")
public String helloWorld() {
throw new MyCustomException("I just can't say hello!");
}
}
It's the same as yours - you can specify anything in the exception.
First:
One of the way of handling it, is to create a class with #ControllerAdvice annotation.
#ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
#ExceptionHandler(MyCustomException.class)
public ResponseEntity<String> handlyMyCustomException(MyCustomException e) {
logger.error("error occurred {}", e);
return new ResponseEntity<>("Something happened: " + e.getMessage(), HttpStatus.I_AM_A_TEAPOT);
}
}
This way you are able to catch the exception of your choice (globally) and return the message with the HTTP Response Status of your choice, not neccessarily I_AM_A_TEAPOT
Second:
#ExceptionHandler(MyCustomException.class)
public ResponseEntity<String> handlyMyCustomException(MyCustomException e) {
logger.error("error occurred {}", e);
return new ResponseEntity<>("Something happened: " + e.getMessage(), HttpStatus.I_AM_A_TEAPOT);
}
You could also create only method annotated with #ExceptionHandler in your controller class - but this is not global and is going to work only for this exact controller calls.
Result below:
Third:
Another way of dealing with exceptions is to create your own error .html files. If you place a file in resources/static/error/500.html it should be returned when the Http-500 Internal Server Error is thrown.

JUnit expected exception not working as expected

i am trying to test a private method inside an ActionListener. The method should throw an exception if an invalid url is passed:
Heres the code of my test:
#Rule
public ExpectedException expectedException = ExpectedException.none();
Map<JLabel, JTextField> inputs;
ActionListener listener;
AddStationWindow window;
ArrayList<Station> stationsToDelete;
#Before
public void setUp() throws IllegalAccessException, NoSuchFieldException,
InstantiationException, SQLException, ClassNotFoundException {
inputs = new HashMap<JLabel, JTextField>();
window = new AddStationWindow();
stationsToDelete = new ArrayList<>();
InitializeH2Database.initialiteDatabase();
}
#Test
public void saveStation() throws NoSuchFieldException,
IllegalAccessException, MalformedURLException, NoSuchMethodException,
InvocationTargetException {
Field f = window.getClass().getDeclaredField("inputElements");
f.setAccessible(true);
LinkedHashMap<JLabel, JTextField> inputs = (LinkedHashMap<JLabel,
JTextField>) f.get(window);
Field f2 = window.getClass().getDeclaredField("save");
f2.setAccessible(true);
JButton saveButton = (JButton) f2.get(window);
inputs.get(window.getInputLabels().get(0)).setText("Testsender");
inputs.get((window.getInputLabels().get(1))).setText("asdasdsa");
ActionListener listener = saveButton.getActionListeners()[0];
Method m = listener.getClass().getDeclaredMethod("saveStation");
m.setAccessible(true);
m.invoke(listener);
expectedException.expect(MalformedURLException.class);
}
#After
public void tearDown() {
stationsToDelete.forEach(s ->
H2DatabaseConnector.getInstance().deleteStation(s));
}
This is the tested method inside the ActionListener:
private boolean saveStation() {
List<JLabel> keys = new ArrayList<>();
for (Map.Entry<JLabel, JTextField> inputElement : inputElements.entrySet()) {
keys.add(inputElement.getKey());
}
String stationName = inputElements.get(keys.get(0)).getText();
String urlString = inputElements.get(keys.get(1)).getText();
URL stationURL = null;
try {
stationURL = new URL(urlString);
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(window, "Invalid URL!", "URL
not valid", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
return false;
}
Station s = new Station(stationName, stationURL);
if (checkStation(s)) {
return WebradioPlayer.addStation(s);
}
return false;
}
If i run the test, i can see that the stack tarce shows the malformed url exception with message no protocol: 'asdasdsa', but the test fails.
Can someone explain me why? JUnit version is 4.
You have to set the expected exception before you call the code that actually does throw the exception.
Instead of
#Test
public void saveStation() throws ... {
// code here
expectedException.expect(MalformedURLException.class);
}
you should write the test method as
#Test
public void saveStation() throws ... {
expectedException.expect(MalformedURLException.class);
// code here
}
Additionally, you have to change your method saveStation to not suppress the exception if you actually want to have it thrown. See #Leviand's answer for more details.
Your test is failing because you are expecting an exception to be thrown (you said invalid url exception), but you are wrapping that exception into a try catch, then you are printing the stacktrace.
try {
stationURL = new URL(urlString);
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(window, "Invalid URL!", "URL
not valid", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
return false;
}
you have to add the trown declaration in your catch, or not catch it at all, ie:
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(window, "Invalid URL!", "URL
not valid", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
throw new MalformedURLException(e);
}
and add the throw info to your method
private boolean saveStation() throws MalformedURLException{

Guice doesn't initialize property

I'm newly with Guice.
I want to use Guice for initializing object without writing new directly.
Here is my main():
public class VelocityParserTest {
public static void main(String[] args) throws IOException {
try {
PoenaRequestService poenaService = new PoenaRequestService();
System.out.println(poenaService.sendRequest("kbkCode"));
} catch (PoenaServiceException e) {
e.printStackTrace();
}
}
}
PoenaRequestService:
public class PoenaRequestService {
private static final String TEMPLATE_PATH = "resources/xml_messages/bp12/message01.xml";
public static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PoenaRequestService.class);
#Inject
#Named("poena_service")
private HttpService poenaService;
public String sendRequest(/*TaxPayer taxPayer,*/ String kbk) throws PoenaServiceException {
LOG.info(String.format("Generating poena message request for string: %s", kbk));
Map<String, String> replaceValues = new HashMap<>();
replaceValues.put("guid", "guid");
replaceValues.put("iinbin", "iinbin");
replaceValues.put("rnn", "rnn");
replaceValues.put("taxOrgCode", "taxOrgCode");
replaceValues.put("kbk", "kbk");
replaceValues.put("dateMessage", "dateMessage");
replaceValues.put("applyDate", "applyDate");
ServiceResponseMessage result;
try {
String template = IOUtils.readFileIntoString(TEMPLATE_PATH);
Document rq = XmlUtil.parseDocument(StringUtils.replaceValues(template, replaceValues));
result = poenaService.execute(HttpMethod.POST, null, rq);
} catch (IOException e) {
throw new PoenaServiceException("Unable to read template file: " + TEMPLATE_PATH, e);
} catch (SAXException e) {
throw new PoenaServiceException("Unable to parse result document, please check template file: " + TEMPLATE_PATH, e);
} catch (HttpServiceException e) {
throw new PoenaServiceException(e);
}
if (result.isSuccess()) {
return (String) result.getResult();
}
throw new PoenaServiceException("HTTP service error code '" + result.getStatusCode() + "', message: " + result.getStatusMessage());
}
}
When I tried to debug this I see next picture:
As e result I got NullPointerException.
I couldn't figure out this behavior. Why does this exactly happen?
Any suggestions?
It's not working because you're not actually using Guice. You need to create an injector and bind your dependencies to something. Something akin to this:
public class VelocityParserTest {
public static void main(String[] args) throws IOException {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
bind(PoenaRequestService.class).asEagerSingleton();
bind(HttpService.class)
.annotatedWith(Names.named("poena_service"))
.toInstance(...);
}
});
try {
PoenaRequestService poenaService = injector.getInstance(PoenaRequestService.class);
System.out.println(poenaService.sendRequest("kbkCode"));
} catch (PoenaServiceException e) {
e.printStackTrace();
}
}
}

assertThat error message for unexpected exception

I have this sort of JUnit test:
#Test
public void testNullCheck() {
String res = someMethod();
assertThat("This is the someMethodTest", res, is(notNullValue()));
}
If someMethod() throws an exception I get a stack trace but the "This is the someMethodTest" is not printed as assertThat() is not called. Is there a somewhat elegant JUnit/hamcrest way to print a custom error message? Eventually I want this in a parametrized test to print the parameter for which the test fails. Note, I don't want to test for a specific exception.
You could create an own Rule that replaces the exception:
public class NiceExceptions implements TestRule {
public Statement apply(final Statement base, final Description description) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (AssumptionViolatedException e) {
throw e;
} catch (Throwable t) {
throw new YourNiceException(t);
}
}
};
}
}
public class YourTest {
#Rule
public final TestRule niceExceptions = new NiceExceptions();
#Test
public void yourTest() {
...
}
}
What about this way:
#Test
public void testNullCheck() {
try{
String res = someMethod();
assertThat("This is the someMethodTest", res, is(notNullValue()));
}catch( Exception e /*or any especific exception*/ ){
fail("This is the someMethodTest Error " + e.getMessage() );
}
}
Using Stefan Birkner's suggestion this is what I came up with. Comments welcome.
package my.test;
import org.junit.internal.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class ExceptionCatcher implements TestRule {
String msg;
#Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (AssumptionViolatedException e) {
throw e;
} catch (AssertionError e){
throw e;
} catch (Throwable t) {
msg = t.getMessage() + "; " + msg;
Throwable cause = t.getCause();
if (cause == null)
cause = t;
StackTraceElement[] stackTrace = cause.getStackTrace();
Throwable t1 = null;
try {
t1 = t.getClass().newInstance();
t1 = t.getClass().getDeclaredConstructor(String.class).newInstance(msg);
t1 = t.getClass().getDeclaredConstructor(String.class, Throwable.class).newInstance(msg, t);
t1.setStackTrace(stackTrace);
throw t1;
} catch (Throwable ignore) {
t1.setStackTrace(stackTrace);
throw t1;
}
}
}
};
}
public void setMsg(String msg) {
this.msg = msg;
}
}
And in the test case:
#Rule
public final ExceptionCatcher catcher = new ExceptionCatcher();
#Before
public void setUp() throws Exception {
catcher.setMsg("....");
}
#Test
public void testNullCheck() {
String res = someMethod();
assertThat("This is the someMethodTest", res, is(notNullValue()));
}

Categories