I created an exception :
public class PkDeleteException extends java.lang.Exception {
private static final long serialVersionUID = 1L;
public PkDeleteException(String msg) {
super(msg);
}
}
Now I threw it in the catch block of some code :
import com.ambre.pta.utils.PkDeleteException;
public class AdminRole {
#Autowired
private Environment env;
#Autowired
private RoleDAO roleDao;
public void del(#RequestParam String id) {
try {
roleDao.delete(id);
} catch (org.hibernate.exception.ConstraintViolationException e) {
Role role = roleDao.get(id);
String errMsg = env.getProperty("admin.list.profils.err.suppr");
errMsg = errMsg.replace("%s", role.getRole_lib());
throw new PkDeleteException(errMsg);
}
}
}
But I got an error Unhandled exception type PkDeleteException !
There are suggested solutions proposed by Eclipse but I do not want to follow them ! So why is there this error ?
In general or for most of the scenarios, you never create a custom exception by extending java.lang.Exception class directly, rather you need to extend java.lang.RuntimeException class (or it's subtypes, which is even more preferable).
As your current PkDeleteException is checked Exception, you need to declare that in your method signature using throws clause (option-2, not preferable) or the best practice is to convert it into unchecked Exception (option-1) like below:
Option(1) - Use unchecked Exception (Preferable):
public class PkDeleteException extends RuntimeExcetion {
private static final long serialVersionUID = 1L;
public PkDeleteException(String msg) {
super(msg);
}
}
Option(2): Change your method signature
from
public void del(#RequestParam String id)
to
public void del(#RequestParam String id) throws PkDeleteException
I suggest you to have a look at here
Your del method should throw PkDeleteException.
Your method should be like follow
public void del(#RequestParam String id) throws PkDeleteException {
try {
roleDao.delete(id);
} catch (org.hibernate.exception.ConstraintViolationException e) {
Role role = roleDao.get(id);
String errMsg = env.getProperty("admin.list.profils.err.suppr");
errMsg = errMsg.replace("%s", role.getRole_lib());
throw new PkDeleteException(errMsg);
}
}
Related
I am trying to catch exceptions generated while executing some methods in a list.
I have created a different POJO class extending throwable class.
public class ErrorDetails extends Throwable implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Exception errorDescription;
public Exception getErrorDescription() {
return errorDescription;
}
public void setErrorDescription(Exception errorDescription) {
this.errorDescription = errorDescription;
}
But still I cannot capture the exception in this manner.
private List<ErrorDetails> hello=new ArrayList<ErrorDetails>();
catch (Exception e) {
hello.add(e);
ErrorDetails is one specific type of Throwable. If you declare a list of ErrorDetails you can't add exceptions or errors in it. Change your code to use a list of Exception instead:
List<Exception> hello = new ...
I don't see a point to have your ErrorDetails class but in case you want to keep it, remove "extends Throwable" or replace it with something else. Throwable is meant to be a parent class only for Exception and Error.
From a single method trowing two different custom exceptions based on the condition. While creating a custom exception passing two things one is an error message and another one is error code as a string. But I'm unable to get the error based on the error code. getting an error while calling processErrorCodes() method. Could anyone please help me in fixing this.
// BackgroundException is a custom EXCEPTION
public class BackgroundException extends Exception {
private static final long serialVersionUID = 4664456874499611218L;
private String errorCode="Unknown_Exception";
public BackgroundException(String message, String errorCode){
super(message);
this.errorCode=errorCode;
}
public String getErrorCode(){
return this.errorCode;
}
}
// Similarly I have InvalidException custom exception
public class MyExceptionTest {
public void methodTest(){
String policyId =null;
String policyNotification = null;
String policyStatus = null;
try {
if(policyNotification !=null) {
if(policyStatus!=null) {
if(policyId!=null) {
}
else{
throw new InvalidException("Policy ID Is Null","POLICY_ID");
}
}else{
throw new BackgroundException("Policy Status Is Null","POLICY_STATUS");
}
}
else{
throw new BackgroundException("Policy Notification Is Null","POLICY_NOTIFICATION");
}
} catch (BackgroundException | InvalidException e ) {
// TODO Auto-generated catch block
try {
processErrorCodes(e);
} catch (MyExcep e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.getMessage();
}
}
private static void processErrorCodes(Exception e) throws BackgroundException,InvalidException {
switch(e.getErrorCode()){
case "POLICY_NOTIFICATION":
System.out.println(e.getMessage());
throw e;
case "POLICY_ID":
System.out.println(e.getMessage());
throw e;
case "POLICY_STATUS":
System.out.println(e.getMessage());
throw e;
default:
System.out.println("Unknown exception occured, lets log it for further debugging."+e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
MyExceptionTest mt = new MyExceptionTest();
mt.methodTest();
}
}
I just want to handle those exceptions based on the error code.
You need a common superclass for all your custom exceptions, let say MessageCodeException, extending Exception and the accept this super class type as a parameter inside of your processErrorCodes method
public abstract class MessageCodeException extends Exception {
public abstract String getCode();
// you can have a same abstract method for message
}
public class BackgroundException extends MessageCodeException {
// ...
}
public class InvalidException extends MessageCodeException {
// ...
}
//and now the process method will look like
private static void processErrorCodes(Exception e) throws ... {
// ...
}
That's abvious that for current implementation you cannot access code field, because Exception class interface does not provide anything like this
BTW it seems to be very bad idea to create Exception driven business validation logic. Wouldn't it be better to create some kind of ValidationResult object with list (lists) of errors/warning/successes and to process such validation result at the end? The purpose of the Exception existence is not to control application flow, but to force user to provide some support for critical situations (or to handle somehow unexpected situations with RuntimeException)
I would like to test the return code of an exception. Here is my production code:
class A {
try {
something...
}
catch (Exception e)
{
throw new MyExceptionClass(INTERNAL_ERROR_CODE, e);
}
}
And the corresponding exception:
class MyExceptionClass extends ... {
private errorCode;
public MyExceptionClass(int errorCode){
this.errorCode = errorCode;
}
public getErrorCode(){
return this.errorCode;
}
}
My unit test:
public class AUnitTests{
#Rule
public ExpectedException thrown= ExpectedException.none();
#Test (expected = MyExceptionClass.class,
public void whenRunningSomething_shouldThrowMyExceptionWithInternalErrorCode() throws Exception {
thrown.expect(MyExceptionClass.class);
??? expected return code INTERNAL_ERROR_CODE ???
something();
}
}
Simple:
#Test
public void whenSerialNumberIsEmpty_shouldThrowSerialNumberInvalid() throws Exception {
try{
whenRunningSomething_shouldThrowMyExceptionWithInternalErrorCode();
fail("should have thrown");
}
catch (MyExceptionClass e){
assertThat(e.getCode(), is(MyExceptionClass.INTERNAL_ERROR_CODE));
}
That is all you need here:
you don't want to expect that specific exception, as you want to check some properties of it
you know that you want to enter that specific catch block; thus you simply fail when the call doesn't throw
you don't need any other checking - when the method throws any other exception, JUnit will report that as error anyway
You can check for it using hamcres matchers as long as thrown.expect is overload to receive Matcher
thrown.expect(CombinableMatcher.both(
CoreMatchers.is(CoreMatchers.instanceOf(MyExceptionClass.class)))
.and(Matchers.hasProperty("errorCode", CoreMatchers.is(123))));
Note that you will need to add hamcrest matcher to your dependencies. Core matched that are included in JUnit is not enough.
Or if you don't want to use CombinableMatcher:
thrown.expect(CoreMatchers.instanceOf(MyExceptionClass.class));
thrown.expect(Matchers.hasProperty("errorCode", CoreMatchers.is(123));
Also, you don't need (expected = MyExceptionClass.class) declaration for #Test annotation
Expanding upon Sergii's answer, you can clean this up even more by writing a custom matcher.
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class CustomMatcher extends TypeSafeMatcher<CustomException> {
public static CustomMatcher hasCode(String item) {
return new CustomMatcher(item);
}
private String foundErrorCode;
private final String expectedErrorCode;
private CustomMatcher(String expectedErrorCode) {
this.expectedErrorCode = expectedErrorCode;
}
#Override
protected boolean matchesSafely(final CustomException exception) {
foundErrorCode = exception.getErrorCode();
return foundErrorCode.equalsIgnoreCase(expectedErrorCode);
}
#Override
public void describeTo(Description description) {
description.appendValue(foundErrorCode)
.appendText(" was not found instead of ")
.appendValue(expectedErrorCode);
}
}
The error code can then be checked like:
import org.junit.rules.ExpectedException;
public class MyObjTest {
#Rule
public ExpectedException thrown = ExpectedException.none();
#Test
public void someMethodThatThrowsCustomException() {
thrown.expect(CustomException.class);
thrown.expect(CustomMatcher.hasCode("110501"));
MyObj obj = new MyObj();
obj.methodThatThrowsCustomException();
}
}
Reference: https://dzone.com/articles/testing-custom-exceptions
I have successfully implemented a custom exception using below code
CarNotFoundException.Java
public class CarNotFoundException extends Exception
{
private static final long serialVersionUID = 1L;
public CarNotFoundException(String msg) {
super(msg);
}
}
Car.Java
public static CarProvider getInstanceByProvider(String provider) throws CarNotFoundException {
if(!provider.equals(Constants.BMW || Constants.B||Constants.C{
throw new CarNotFoundException("Car Not Found");
}
return carProvider;
}
CarTest.java
try
{
carProvider = Car.getInstanceByProvider(provider);
} catch (CarNotFoundException e) {
e.printstacktrace();
}
What I want to do ?
Instead of e.printStackTrace(); when I calle.getMessage(),
I get nothing(blank).
How I can make custom e.getMessage() ?
Edit : I got my answer, I missed System.out.println()
Thanks for helping..!
Override getMessage() method in your custom exception
public class CarNotFoundException extends Exception
{
private static final long serialVersionUID = 1L;
public String message;
public CarNotFoundException(String msg) {
this.message = msg;
}
// Overrides Exception's getMessage()
#Override
public String getMessage(){
return message;
}
}
Jmockit is very powerful, but sometimes I cannot understand what it does behind the scene, so I have a question regarding jmockit. Hopefully the more experienced programmers on here could help shine some light on this situation :)
I have the following two classes in two separate files:
public class SmallClass {
String a;
SmallClass(String arg) throws Exception {
a = arg;
}
public String getString() {
return a;
}
}
And
public class BigClass {
private static final SmallClass smallClass;
static {
try {
smallClass = new SmallClass("dummy");
} catch (Exception e) {
throw new IllegalStateException("Could not initialized", e);
}
}
public static String getString() {
return smallClass.getString();
}
}
Now, I have a class to test BigClass:
public class BigClassTest {
#Test
public void testGet() throws Exception {
///CLOVER:OFF
new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception {
//Do nothing
}
#Mock
public String getString() {
return "dummyString";
}
};
///CLOVER:ON
Assert.assertEquals("dummyString", BigClass.getString());
}
#Test(expected = ExceptionInInitializerError.class)
public void testException() throws Exception {
///CLOVER:OFF
new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception{
throw new Exception("Mocked Exception");
}
};
///CLOVER:ON
BigClass.getString();
}
}
If I run each of these independently, then they each passes. But if I run the whole test file, then the first test fails with:
java.lang.NoClassDefFoundError: Could not initialize class BigClass
I also tried tearing down the mock after each test like this, but it doesn't help:
public class BigClassTest {
MockUp<SmallClass> smallClassMockUp;
#Test
public void testGet() throws Exception {
///CLOVER:OFF
smallClassMockUp = new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception {
//Do nothing
}
#Mock
public String getString() {
return "dummyString";
}
};
///CLOVER:ON
Assert.assertEquals("dummyString", BigClass.getString());
smallClassMockUp.tearDown();
}
#Test(expected = ExceptionInInitializerError.class)
public void testException() throws Exception {
///CLOVER:OFF
smallClassMockUp = new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception{
throw new Exception("Mocked Exception");
}
};
///CLOVER:ON
BigClass.getString();
smallClassMockUp.tearDown();
}
}
Any help would be appreciated. Thank you in advance!
The occurrence of NoClassDefFoundError, in a case like this, is not because the class wasn't found by the JVM (it was), but because its static initialization has failed (by throwing an exception or error from the execution of a static initializer). Once this happens, the class is left in an invalid/uninitialized state and cannot be used in the same JVM instance anymore.
For reference, see the "Initialization of classes and interfaces" section in the JLS.
Also, note that the order in which tests execute is not necessarily the textual order they appear in the test class. Here, testException (the second test) runs first. So, when testGet runs, the class is invalid and the JVM throws the error.