This question already has answers here:
Catching an Exception from a called Method
(4 answers)
Closed 7 years ago.
i seem to be a bit confused on how to throw exceptions and when it would be used to create your own exceptions.
i have this code and was wondering if i went about this the correct way
heres the method:
public void setHireYear(int year) throws Exception {
try{
if (year <= CURRENT_YEAR && year >= CURRENT_YEAR - MAX_YEARS_WORKED) {
hireYear = year;
}
else{
throw new HireYearException(year);
}
}catch(HireYearException e){
e.toString();
}
}
and heres the exception class:
public class HireYearException extends Exception
{
private int hireYear;
/**
* Constructor for objects of class HireYearException
*/
public HireYearException(int hireYear)
{
this.hireYear = hireYear;
}
public String toString()
{
return "Hire year cannot exceed Current year, your hire year is - " + hireYear;
}
}
why would throwing a custom exception be better than throwing pre defined exceptions?
Specific customs exceptions allow you to segregate different error types for your catch statements. The common construct for exception handling is this:
try
{}
catch (Exception ex)
{}
This catches all exceptions regardless of type. However, if you have custom exceptions, you can have separate handlers for each type:
try
{}
catch (CustomException1 ex1)
{
//handle CustomException1 type errors here
}
catch (CustomException2 ex2)
{
//handle CustomException2 type errors here
}
catch (Exception ex)
{
//handle all other types of exceptions here
}
Hence it provides you (benefits and why to create it)
1.specific exceptions allow you a finer level of control over your exception handling
2.Provides a type safe mechanism for a developer to detect an error condition.
3.Add situation specific data to an exception
Ideally this data would help another developer track down the source of the error.
4.No existing exception adequately described my problem
Source
Related
I am new to android apps development. Recently,Im writing an application which able to show public ip based on Ipify. So far, i already:
Download the required jar file and put inside libs folder
I also compile file within gradle
Then i import required class it to my class
How to use Ipify, according to its website:
import org.ipify.Ipify;
public class HelloIP {
public static void main(String[] args) throws IOException {
System.out.println(Ipify.getPublicIp());
}
}
I write the following method to be invoked from another class:
public static String getPublicIp() throws IOException{
String ip = Ipify.getPublicIp();
return ip;
}
Another Class
//Get wifi
getWifiName wifiInfo = new getWifiName();
String myIP = wifiInfo.getPublicIp();
However, i keep getting:
Error:(52, 43) error: unreported exception IOException; must be caught
or declared to be thrown
I tried to modify the code and use the following try and catch, but still got the same error.
public static String getPublicIp() throws IOException{
String myip = Ipify.getPublicIp();
try{
return myip;
}
catch (IOException e){
System.out.println("General I/O exception: " + e.getMessage());
e.printStackTrace();
}
}
Im not too good in catch and throw exception, and already spent the whole day for this.I dont have idea anymore to fix this error..T.T
public static String getPublicIp() {
try{
return Ipify.getPublicIp();
}catch (IOException e){
System.out.println("General I/O exception: " + e.getMessage());
e.printStackTrace();
}
return null;
}
In case it didn't help, clean project in your IDE. You may have some data cached and it might be a reason.
Your problem is in another class! As you have declared the method getPublicIp() to throw IOException that class is afraid of receiving the Exception and therefor requests catching it.
In Java you have two types of Exceptions. Checked and unchecked. Checked Exceptions must be caught.
In Java Exceptions are used for marking unexpected situations. For example parsing non-numeric String to a number (NumberFormatException) or calling a method on a null reference (NullPointerException). You can catch them in many ways.
Unchecked Exceptions are those which extend RunTimeException. They are used for marking unexpected states usually caused by user's input. They shouldn't cause harm and should be worked out with business logic. You don't have to catch them, but sometimes you should.
On the other hand there are Checked Exceptions which mark dangerous situations. For example the application being unable to open a file. As those situations are found dangerous, you must catch them.
try{
//some code
} catch (NumberFormatException e1) {
e.printStackTrace() //very important - handles the Exception but prints the information!
} catch (NullPointerException e2) {
e.printStackTrace();
}
or using the fact, that they all extend Exception:
try {
//somecode
} catch (Exception e) {
e.printStackTrace;
};
or since Java 7:
try {
//somecode
} catch (NullPointerException | NumberFormatException e) {
e.printStackTrace;
};
I have a unique constraint on one of my entities and whenever I get a PSQLException which occurs whenever that constraint is violated, I want to respond with a bad request.
This is my exception handler which I tried to implement:
#ControllerAdvice
public class DatabaseExceptionHandler {
#ExceptionHandler(value = PSQLException.class)
#ResponseStatus(HttpStatus.BAD_REQUEST)
public void handleDatabaseExceptions(PSQLException e) {
// i want to respond with a bad request only when this condition is satisfied
//
// if (e.getSQLState().equals("23505")) {
//
// }
}
}
And this is where the model is saved in db:
public DepartmentForHoliday setDepartment(DepartmentForHoliday department) {
if (department.getDepartmentId() == null) {
Department savedDepartment = new Department();
savedDepartment.setName(department.getName());
try {
departmentRepository.save(savedDepartment);
} catch (PSQLException e) {
/*here i have a compiler error which says that this exception is never thrown in the corresponding try block, but where ?*/
}
}
This is the exception that is thrown when I add a duplicate entry:
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "uk_1t68827l97cwyxo9r1u6t4p7d"
Detail: Key (name)=(Tech) already exists.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2458) ~[postgresql-9.4.1211.jre7.jar:9.4.1211.jre7]
How to handle PSQLExceptions ? Should I make my own exception as a wrapper or how to solve this problem ?
Key problem is that PSQLException is wrapped into some Spring exception (which I assume from your code); you have to unwrap it (for example using guava's Throwables):
public DepartmentForHoliday setDepartment(DepartmentForHoliday department) {
if (department.getDepartmentId() == null) {
Department savedDepartment = new Department();
savedDepartment.setName(department.getName());
try {
departmentRepository.save(savedDepartment);
} catch (RuntimeException e) {
Throwable rootCause = com.google.common.base.Throwables.getRootCause(e);
if (rootCause instanceof SQLException) {
if ("23505".equals(((SQLException) rootCause).getSQLState())) {
// do smth interesting :)
}
}
}
}
}
Once you do that you can throw your custom exception and handle it in DatabaseExceptionHandler
You are catching PSQLException. Instead of that, please catch SQLException. With SQLException you will can handle all this SQL exceptions.
You can check the SQLException knowledge at this link
Then in your code just treat the SQLException as you want. The most generic catch clause is the following one:
catch (SQLException e)
{
System.out.println("ERROR: Fetch statement failed: " +
e.getMessage());
}
With this code you are printing the exception. If you want more information, check this
This is quite late, but building on previous responses I was able to solve it as so:
try {
return this.projectRepository.saveAndFlush(patchedProjectEntity);
} catch (DataIntegrityViolationException e) {
if (e.getMostSpecificCause().getClass().getName().equals("org.postgresql.util.PSQLException") && ((SQLException) e.getMostSpecificCause()).getSQLState().equals("23505"))
throw new UniqueConstraintViolationException("", e.getMostSpecificCause());
throw e;
}
Where UniqueConstraintViolationException is a custom exception and handled with a spring controller advice.
You might as well register an exception handler for that wrapped exception (that #radek mentioned) directly.
In your case that's:
#ExceptionHandler(DataIntegrityViolationException::class)
protected fun handleDataIntegrityException(ex: DataIntegrityViolationException, request: WebRequest) : ResponseEntity<SomeBody>{
return ResponseEntity.badRequest().body(someBodyHere)
}
The error is converted within convertHibernateAccessException in org.springframework.orm.jpa.vendorHibernateJpaDialect, which has already processed away from PSQL. You can add a breakpoint there and follow the stacktrace.
There is a lot of proxy'ing happening under the hood, but the takeaway is that there is always a readable, expressive Exception to use directly.
So, I had to create two files. One is a class definition. The other one uses the class' methods/fields.
(Artifact.java) Artifact Class definition:
public class Artifact {
int artNumber;
String arcName;
String artType;
int artYear;
double artWeight;
Artifact(int artNumber, String arcName, String artType, int artYear,double artWeight) {
this.artNumber = artNumber;
this.arcName = arcName;
this.artType = artType;
this.artYear = artYear;
this.artWeight = artWeight;
}
public void changeArtYear(int x) {
this.artYear = x;
}
public void changeArcName(String x) {
this.arcName = x;
}
public int getArtNumber() {
return artNumber;
}
public String getArcName() {
return arcName;
}
public String getArtType() {
return artType;
}
public int getArtYear() {
return artYear;
}
public double getArtWeight() {
return artWeight;
}
public String toString(){
return("The artifact #"+artNumber+" was discovered by "+arcName+". The artifact is made of "+artType+" and was discovered in "+artYear+". The artifact weighs "+artWeight+" kilograms.");
}
}
(ArtifactTester.java) Testing methods:
public class ArtifactTester {
public static void main(String[] args){
Artifact test = new Artifact(88888888,"ben","clay",1624,46.4);
System.out.println(test.toString()); //toString()
System.out.println(test.getArtWeight()); //getArtWeight()
System.out.println(test.getArtYear()); //getArtYear()
System.out.println(test.getArtType()); //getArtType()
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtNumber()); //getArtNumber()
test.changeArcName("zack");
test.changeArtYear(1400);
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtYear()); //getArtYear()
}
}
Anyways, my teacher to told me to add exception handling, but I am not sure where I would add exception handling.
Question: Is it possible to use exception handling in this situation?
Well to be blunt. Yes. Of course. You can use exception handling wherever and whenever you please (most of the time). Although, in this specific case I don't really see a good reason for it. But, I'll take your word for the need.
Now, as for where to handle exceptions, this is up to you. You can add exception handling in one of two places. You can either add exception handling when you call the methods like this:
try { //try executing a block of code which may throw exception
test.toString()
}
catch(Exception e) { //use Exception for all types of exceptions, or make it specific
//do something here if the exception is thrown
}
or you can excpetion handle in the methods themselves like so:
public void changeArtYear(int x) {
try{
this.artYear = x;
}
catch(Exception e){ //catch the exception that could be thrown
//do something
}
}
This should do the trick in your case if you want to add exception handling here. However, I would strongly urge you to learn exception handling and the different exceptions in Java, it is one of the most improtant fundamentals to programming in this language.
Also, let me point this out again: In this program, there is really no need to use exception handling except for practice. There is nothing here that would throw an exception for any reason. (Except maybe a NullPointerException if you passed a null parameter through one of your method calls)
Good Reference/Tutorial:
http://www.tutorialspoint.com/java/java_exceptions.htm
This site is an excellent java reference point in general, but specifically for your question today, this page shows you how to work with exceptions.
Is it possible to use exception handling in this situation?
I don't think so. You should probably go and ask your teacher.
In your code, Artifact is just a POJO (Plain Old Java Object). It would not throw any exceptions. All you do in the class is getters and setters, right? How can that throw any exceptions?
You can throw exceptions though. In your setters, you can check whether the argument is null before setting it to the fields. For example:
public void changeArcName(String x) {
if (x == null) throw new ArgumentException ("x is null!");
this.arcName = x;
}
Alternatively, you can just use brute force and use try...catch. like this:
Artifact test = new Artifact(88888888,"ben","clay",1624,46.4);
try {
System.out.println(test.toString()); //toString()
System.out.println(test.getArtWeight()); //getArtWeight()
System.out.println(test.getArtYear()); //getArtYear()
System.out.println(test.getArtType()); //getArtType()
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtNumber()); //getArtNumber()
test.changeArcName("zack");
test.changeArtYear(1400);
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtYear()); //getArtYear()
} catch (Exception ex) {
ex.printStackTrace ();
}
Warning: The catch block can never be reached!
I don't know whether the above is what your teacher wants. Just try both methods and hand it in and see what he/she says!
This is my Exception:
public class MyException extends Exception {
private String errorCode="Unknown_Exception";
public MyException(String message, String errorCode){
super(message);
this.errorCode=errorCode;
}
public String getErrorCode(){
return this.errorCode;
}
}
Now immagine the next scenario, the code is way too long to paste here:
1 I got a Presentation class made in Swing in Presentation package
2 In package calculations I made simple operations with few numbers from received database fields
3 In package connections I got the database connections
Trouble comes here:
-In presentation layer I catch all errors, like this:
try {
//here is a method called updateCombo() wich throws:
//throw new MyException(e.getMessage(),"ERROR_UPDATING_COMBO_BOX");
} catch (MyException ex) {
try {
//Here we process error code, if error is not defined, uses default errors.
processCode(ex);
} catch (MyException ex1) {
Logger.getLogger(Presentacion.class.getName()).log(Level.SEVERE, null, ex1);
}
}
processCode is a simple list with cases, like this:
private void processCode(MyException e) throws MyException {
switch (e.getErrorCode()) {
case "ERROR_UPDATING_COMBO_BOX":
lblErrorText.setText("Error updating combo.");
throw e;
case "ERROR_SELECTING_PRIMARY_KEY":
lblErrorText.setText("Error selecting PK");
throw e;
case "ERROR_OPENING_CONNECTION":
lblErrorText.setText("Error opening connection.");
throw e;
default:
lblErrorText.setText("Excepcion not defined: "+ e.getMessage());
e.printStackTrace();
}
This is the scenario, the connection fails in 3rd package and leads to this:
throw new MyException(e.getMessage(),"ERROR_OPENING_CONNECTION");
As I said, the error is thrown to the upper layer with throws clause in method header, this beeing 2nd package.
2nd package also throws a new exception to Presentation, because of failing connection:
throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");
Presentation methods also throw this exception becase 2nd layer failed:
throw new MyException(e.getMessage(),"ERROR_UPDATING_COMBO_BOX");
The main problem:
Using debug i found out that the program does what it has to do. It gets to the connection layer and does this successfully:
throw new MyException(e.getMessage(),"ERROR_OPENING_CONNECTION");
But, in 2nd layer, calculations, if connection fails it throws a new exception:
throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");
This is the problem:
throw new
throwing new exception overrides ERROR_OPENING_CONNECTION with ERROR_SELECTING_PRIMARY_KEY. When it gets to presentation due to its "throw new" overrides ERROR_SELECTING_PRIMARY_KEY with ERROR_UPDATING_COMBO_BOX, resulting in the final error shown in the screen:
lblErrorText.setText("Error updating combo.");
Is there any way to return to presentation once first error is caught without overriding by next errors?
Maybe I misunderstood the concept but I want to catch all possible errors because:
-If connection is OK but method in 2nd layer fails it should throw ERROR_SELECTING_PRIMARY_KEY.
-If 2nd layer (calculations) does it OK but there is error in presentation it should lead to ERROR_UPDATING_COMBO_BOX.
You can use e.getCause() which will return a Throwable and check if this cause belongs to MyException. In case it is, you can check the e.getCause() again recursively until you obtain the deepest error code in the stacktrace and perform the validation for this exception.
Here's an example:
public MyException getDeepestException(MyException e) {
Throwable t = e.getCause();
if (t instanceof MyException) {
return getDeepestException((MyException)t);
}
return e;
}
As pointed out by #RealSkeptic, in order to use this approach, you will need to add an additional constructor to your custom exception:
public MyException(String message, Throwable cause, String errorCode){
super(message, cause);
this.errorCode = errorCode;
}
And when throwing your exception, call the proper constructor:
try {
//...
} catch (SomeException e) {
throw new MyException(<a proper message should be here>, e, "ERROR_SELECTING_PRIMARY_KEY");
}
If I understand you correctly, if the exception caught by one package happens to be a MyException, you want the original MyException to be passed up, otherwise (if the exception is some other type of Exception) you want to create a new MyException.
In this case, you should have two catch clauses.
try {
// Whatever you do in the try clause
} catch ( MyException myEx ) {
throw myEx;
} catch ( Exception e ) {
throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Log runtime Exceptions in Java using log4j
I am developing a desktop application. I used Log4j to write log. How can I write log with NullPointerException? I didn't predict that could happen.
If you mean just how to print the exception to the log, assuming the configuration is OK:
try {
....something
} catch(RuntimeException e) {
log.error("Got unexpected exception", e);
}
NullPointerException inherits from RuntimeExepction so you can safely catch it and any other runtime ones with the above code.
The above code will NOT catch any exception which is inherit from Exception but not from RuntimeException.
If I understand your question properly, you do not want to put Try catch statements throughout your code to handle NullPointer Exception as it is not expected.
Simple way to handle is to put a null check before using the object reference for any operation. Also , place these null checks only on those objects where you can expect that it might not be initialized due to some other exception or error scenario.
i.e
if (objectReference!=null)
objectReference.CallSomeMethod();
Another example
String listofDefaulters =null;
String defaulters = getDefauter();
/**you might expect that you will always get defaulters from the method call but it might happen dat it can return null value also.
So always put a null check where you are not 100% sure if value will not be null**/
if (defaulters !=null)
defaulters.doSomeOperation();
If you want to do aspect oriented programming, you may want to write an advice around Exception including NullPointerException and perform the logging e.g. below:
#Aspect
public class ExceptionLogging {
private static Logger log = null;
#Pointcut ("call(* *.*(..)))
public void exceptionLogMethods(){
}
#AfterThrowing(pointcut="exceptionLogMethods()", throwing="e")
public void handleException(Throwable ex, JoinPoint jointPoint) {
log = Logger.getLogger(jointPoint.getThis().getClass());
log.debug(jointPoint.getThis().getClass() + ex.getMessage());
}
}
You can use the class Preconditions too in the Guava libraries for customize the exceptions and the messages.
The method Preconditions#checkNotNull(T, java.lang.Object) throws a NullPointerException if the reference T is null.
void method(String name) {
Preconditions.checkNotNull(name, "The name is null.");
// do something with the name
}
void otherMethod() {
try {
method("zerone"); // OK
method(null); // throws NPE
} catch(RuntimeExcetion e) {
LOG.error(e.getMessage(), e); // Message: "The name is null."
}
}