Trouble with unhandled exceptions - java

I have two methods. Method A calls method B. I cannot change the exceptions of neither (homework demands). However, the 2 exceptions mean the exact same thing, so when I call method B on A, I already know that B's exception is not getting thrown. However, I still get the "unhandled exception" error from Eclipse. How can I avoid it?
Here are the methods
public void createProfile(Profile user) throws PEException {
Vector<Profile> p = new Vector<Perfil>();
try{
if (repository.search(user.getUsername()) == null) {
repository.register(user); //error on this line when I call the method on main
}
else {
throw new PEException(user.getUsername());
}
} catch (PEException e){
e.printStackTrace();
}
}
public void register(Profile user) throws UJCException {
try {
if (this.search(user.getUsername()) == null) {
this.users.add(user);
}
else {
throw new UJCException(user.getUsername());
}
} catch (UJCException e) {
e.printStackTrace();
}
}
I MUST NOT change the definitions of the methods (I can't throw UJCException on createProfile). Thanks in advance

You shouldn't be throwing the exceptions and then catching them inside the same method. That defeats the purpose of throwing the exception in the first place. the methods which calls your 2 methods should expect nothing (void) or the exception in the event that something went wrong. Make sure your methods createProfile() and register() can actually throw their exception so methods calling them can catch the exception and do whatever it is they need to when the exception is thrown.
public void createProfile(Profile user) throws PEException {
Vector<Profile> p = new Vector<Perfil>(); //not being used...
if (repository.search(user.getUsername()) == null) {
try{
repository.register(user);
}catch(UJCException e){
e.printStackTrace();
throw new PEException(user.getUsername());
}
}
else {
throw new PEException(user.getUsername());
}
}
public void register(Profile user) throws UJCException
{
if (this.search(user.getUsername()) == null) {
this.users.add(user);
}
else {
throw new UJCException(user.getUsername());
}
}
Now when you call these methods wrap the call in a try catch and catch the appropriate exception depending on which method was called

Related

How to throw an Exception to the method caller inside a try catch body?

I am not able to throw a custom exception from within a try block. The exception doesn't return back to the caller, instead jumps out of the try-catch block and executes the remaining statements (return i; statement in the code).
I know that I don't need the try-catch block for the function "exceptionTester" to run. However I'd like to know the reason for this behaviour. exceptionTester(0) returns 0 instead of the exception being thrown.
public class Test {
public static int exceptionTester(int i) throws FAException{
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (Exception e) {
// TODO: handle exception
}
return i;
}
public static void main(String[] args) {
try {
int in = exceptionTester(0);
System.out.println(in);
} catch (FAException e) {
System.out.println(e.getStatusCode());
}
}
}
public class FAException extends Exception {
private String statusCode;
public FAException(String statusCode, String message, Throwable cause){
super(message,cause);
this.statusCode = statusCode;
}
public String getStatusCode() {
return this.statusCode;
}
}
You are throwing a FAException and you want to re-throw it. Either remove the try-catch entirely, or catch that specific exception (if you insist) like
public static int exceptionTester(int i) throws FAException{
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (FAException e) {
throw e; // <-- re-throw it.
}
return i;
}
It is also possible to throw a new FAException wrapping some other type of exception in the catch. Which might look like,
} catch (Exception e) {
throw new FAException("Status Code", "Original Message: " + e.getMessage(), e);
}
You are catching any exception that extends from Exception. FAException extends Exception so in your method exceptionTester(int) you are throwing FAException and immediatelly catching it. Since catch block does nothing, it continues in method processing. That's why return is reached.
If you want to catch any exception that can occur in method and rethrow it as your exception then:
public static int exceptionTester(int i) throws FAException{
try {
// some code that throws an exception
// e. g. dividing by zero, accessing fields of null object, ...
} catch (Exception e) {
throw new FAException("Ooops", "Something went wrong", e);
}
return i;
}
If you want to throw an exception when some criteria is met:
public static int exceptionTester(int i) throws FAException {
if (i == 0) {
throw new FAException("IllegalArgument", "arg can not be 0", null);
}
return i;
}
It is simply because you are not rethrowing the caught exception in the main method.
Even if you do this:
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (Exception e) {
throw e; --> catching FAException and throwing it to the caller
// 'e' is of type FAException (though you caught it as Exception)
}
return i;
}
It should work, and you won't even hit the "return i" statement.
Otherwise (if no re-throwing, the catch statement will handle the exception and not the caller).
Rest, I agree with the above answer.

How to eliminate the duplicate try-catch code in similar methods?

I have the following insert/update methods in my service:
#Override
public void insertEntity(Entity entity) {
try {
entityDao.insert(entityMapper.entityToEntityDO(entity));
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
#Override
public void updateEntity(Entity entity) {
try {
entityDao.update(entityMapper.entityToEntityDO(entity));
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
As you can see, the actual logic of insertEntity and updateEntity is very simple. In order to throw a custom Exception, I did some database error code check. Since the two methods all need this kind of checking, the code duplicated in both methods, which is obviously a code smell.
How can I eliminate this kind of code duplication?
Extract the common catch-block to a method which throws DataIntegrityViolationException.
You can create Interface like this:
public interface ConsumerWithException<T, V extends Exception> {
/**
* Performs this operation on the given argument.
*
* #param t the input argument
*/
void accept(T t) throws V;
}
Use it a private method like:
private void action(ConsumerWithException<Entity, DataIntegrityViolationException> doAction, Entity entity){
try {
doAction.accept(entity);
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
You can put the code inside the catch block into a separate method.
Alternatively, You can catch Exception and write a handler method to handle the exceptions if in future you expect to handle multiple exceptions there.
You can declare your methods to throw the exception, then try/catch in one place where your methods are called. For example:
public void insertEntity(Entity entity) throws DataIntegrityViolationException {}
public void updateEntity(Entity entity) throws DataIntegrityViolationException {}
try {
insertEntity(entity);
updateEntity(entity);
catch (DataIntegrityViolationException e) {
// handle exception
}

Handle Exception after all lines have been finished execution without finally

I need methodA2 also gets executed even though there is an exception by methodA1(). Here I have added only two methods as methodA1() and methodA2(). Let's say there are many methods. In that case also, the solution should be able to applicable.
class A {
String methodA1() throws ExceptionE {
// do something
}
String methodA2() throws ExceptionE {
// do something
}
}
class C extends A {
String methodC() throws ExceptionE2 {
try {
methodA1();
methodA2();
} catch (ExceptionE e) {
throw new ExceptionE2();
}
}
}
Please note that there can be many methods invoked with methodA1, methodA2. In that case having multiple try, catch, finally will look ugly.. So are there any other methods to do that?
I need to store error information in a log file. In methodA1(), methodA2() ... information in each tag is get validated. what I want is having all the error information in log file. Once exception throws it will generate log file. So I will miss validation information from other tags. So we can't go for finally approach.
You can use a loop with Java 8 lambdas:
interface RunnableE {
void run() throws Exception;
}
class Example {
public static void main(String[] args) {
List<RunnableE> methods = Arrays.asList(
() -> methodA1(),
() -> methodA2(),
() -> methodA3()
);
for (RunnableE method : methods) {
try {
method.run();
} catch (Exception e) {
// log the exception
}
}
}
private static void methodA1() throws Exception {
System.out.println("A1");
}
private static void methodA2() throws Exception {
System.out.println("A2");
}
private static void methodA3() throws Exception {
System.out.println("A3");
}
}
Please note that the interface is needed only when methods throw checked exception. If they were throwing only runtime exceptions, you could use java.lang.Runnable instead.
No other way. If each method can throw exception, but you want to continue execution of remaining methods anyway, then each method call must be in its own try-catch block.
Example:
List<Exception> exceptions = new ArrayList<>();
try {
methodA1();
} catch (Exception e) {
exceptions.add(e);
}
try {
methodA2();
} catch (Exception e) {
exceptions.add(e);
}
try {
methodA3();
} catch (Exception e) {
exceptions.add(e);
}
if (! exceptions.isEmpty()) {
if (exceptions.size() == 1)
throw exceptions.get(0);
throw new CompoundException(exceptions);
}
You will of course have to implement the CompoundException yourself.

Catch exceptions without a try block?

I have a lot of custom exceptions that I'm throwing in a specific cases in the code, and I'd like to have one catch block at the bottom of the method to handle them all.
All the exceptions are children of the Exception class CribbageException, so I'd like to have:
public void myMethod(){
if (whatever){
throw new CardException();
}
if (something else){
throw new InvalidCardException();
}
if (scenario 3){
throw new TwoCardsException();
}
catch (CribbageException e) {
System.out.println(e.getMessage());
}
}
But I'm getting a catch without try error.
Is there any way to use this type of exception handling?
Wrap all the throws inside a single try.
public void myMethod(){
try {
if (whatever){
throw new CardException();
}
if (something else){
throw new InvalidCardException();
}
if (scenario 3){
throw new TwoCardsException();
}
}
catch (CribbageException e) {
System.out.println(e.getMessage());
}
}

Exceptions works correct but not how its must

The method processExceptions() should call the method BEAN.methodThrowExceptions and handle exceptions:
1.1. if an exception FileSystemException occurs, then log it by calling the method BEAN.log and throw forward
1.2. if an exception CharConversionException or any other IOException occurs, just log it by calling the method BEAN.log
Add the class/type of the exception you are forwarding in 2.1. to the processExceptions() method signature.
Handle the remaining exception in the method main() and log it. Use try..catch
I tried different solutions. It works but not as it should. What is the correct placement of throws in methods. Or maybe i shouldnt use them at all? And if I don't place them I can't make use of throw. Please help, I would really appreciate your time.
public class Solution {
public static StatelessBean BEAN = new StatelessBean();
public static void main(String[] args) {
try{
processExceptions();
}
catch (CharConversionException e){
BEAN.log(e);
}
}
public static void processExceptions()throws CharConversionException {
try{
BEAN.methodThrowExceptions();
}
catch (CharConversionException e){
BEAN.log(e);
throw e;
}
catch (FileSystemException e){
BEAN.log(e);
}
catch (IOException e){
BEAN.log(e);
}
}
public static class StatelessBean {
public void log(Exception exception) {
System.out.println(exception.getMessage() + ", " + exception.getClass().getSimpleName());
}
public void methodThrowExceptions() throws CharConversionException, FileSystemException, IOException {
int i = (int) (Math.random() * 3);
if (i == 0)
throw new CharConversionException();
if (i == 1)
throw new FileSystemException("");
if (i == 2)
throw new IOException();
}
}
}
If a method is capable of throwing an exception which IS NOT RuntimeException (either directly throwing or invoking a method which can throw an exception), it should either handle the exception or declare that it throws the exception, so that any other method which calls this method would know that it can encounter an exception and can either handle it or declare it that it throws (and so on).
Since you are dealing with checked exception, there is no clean way to avoid declaring throws, but there is a (messy) workaround. You can wrap the exception in a RuntimeException and can throw it and when you want to handle it, you can get the actual exception from the re.getCause();
public class Solution {
public static StatelessBean BEAN = new StatelessBean();
public static void main(String[] args) {
try{
processExceptions();
}
catch (RuntimeException re){
if (!(re.getCause() instanceof CharConversationException)) {
//handle the case in which the exception was not CCE and not FSE not IOException
}
}
}
public static void processExceptions() {
try{
BEAN.methodThrowExceptions();
} catch (CharConversionException cce){
BEAN.log(e);
throw new RuntimeException(cce);
} catch (FileSystemException fse){
BEAN.log(e);
} catch (IOException e){
BEAN.log(e);
}
}
public static class StatelessBean {
public void log(Exception exception) {
System.out.println(exception.getMessage() + ", " + exception.getClass().getSimpleName());
}
public void methodThrowExceptions() throws CharConversionException, FileSystemException, IOException {
int i = (int) (Math.random() * 3);
if (i == 0)
throw new CharConversionException();
if (i == 1)
throw new FileSystemException("");
if (i == 2)
throw new IOException();
}
}
}
I am not sure whether I understood your question correctly and this is what you wanted :)
I think that the order:
Handle the remaining exception in the method main()
means that you should catch not only CharConversionException, but all other Exceptions by:
catch (Exception e)
Besides, you should ask it on help.javarush.net I think :>

Categories

Resources