Custom Unchecked Exceptions - java

Okay guys I've been trying to figure this out for the past day or so. My homework assignment has me creating both Unchecked and Checked Exceptions. The checked exceptions I believe I get basically they must be handled before compiling (With try & catch or throwing it to the next thing that calls it. For unchecked exceptions I don't understand how custom ones work. They are caught at runtime and don't necessarily need to be thrown or encased with try & catch but if they're custom how does the IDE or whatever know what to look for? Example: One of my custom Unchecked files is supposed to trigger if the user adds a pokemon but the party is full, but how do I tell the IDE that that's what needs to happen? My Exception file looks like:
public class PartyIsFullException extends RuntimeException {
public PartyIsFullException() {
super();
}
public PartyIsFullException(String message) {
super(message);
}
}
and then I want to implement it in this method, but idk how to do it. I realize now I can't throw them because the user won't be expecting them and therefore won't try to catch them.
public void addToParty(String name) throws PartyIsFullException {
boolean exists = false;
for (int i = 0; i < 152; i++) {
exists = (name.equals(pokedex[i]));
}
if (exists) {
throw new PokemonAlreadyExistsException();
} else {
if (partyPos < 6) {
party[partyPos] = name;
partyPos++;
} else {
throw new PartyIsFullException();
}
}
}

I realize now I can't throw them because the user won't be expecting them and therefore won't try to catch them.
You can throw them!
In a real project, it should be clearly documented.
/*
* #throws PartyIsFullException if isPartyFull() would return true
*/
public void addToParty(String name) throws PartyIsFullException {...}
Usually an unchecked exception is used for a situation where the client of the method is avoiding the exceptional condition themselves e.g.:
if(theParty.isPartyFull()) {
// tell the user the party is full
// and they can't add more Pokemon
} else {
theParty.addToParty(thePokemon);
}
And thus they shouldn't have to explicitly catch it because they are already handling that circumstance.
If the exception is thrown and there is not a try-catch outside, it will throw all the way up to terminate the thread. (For a small program with just main, this means the program crashes.)

Although you don't know if a certain custom unchecked exception could or not be thrown from a certain method you still can catch it (or it's superclass Exception). Having custom exception against provided by Java could add some useful details specific for your exceptional case (i.e. exception name should be meaningful so that it makes it easier to read your logs).
Custom (unchecked) exception creation and it's content could also be tuned to suit your particular need. E.g. PartyIsFullException constructor could take a Party object and format it's state into a String.
In case you don't need to facilitate your unchecked exception creation/presentation it's OK to go with RuntimeException assuming you provide a descriptive message.

Related

Java: How to propagate a "method exit" when tucking-in exceptions?

By "method exit" - I mean the actions in a method such as return or throw new... that the compiler considers the end of a method - if you could please tell me the accepted word for "method exit", I will edit the question
My problem is the following:
I do a lot of throw new RuntimeException(...
So, I decided to "tuck it in" as:
public static void quickRaise (String msg) { throw new RuntimeException(msg); }
And then I can reuse it.
(This will help me in the future to enhance the procedure around raising Runtime Exceptions and even
switch to a custom Exception class, without fishing in the code for exception throws)
However, where before I could write:
public MyType doSomething() {
try {
//...
return new MyType (parameter);
} catch (Exception e) {
throw new RuntimeException("msg")
}
}
And the compiler would correctly understand that "this method either exits by return or by throw" and therefore there are no logical "dead ends"
When I changed throw new RuntimeException("msg") to quickRaise("msg"), the compiler no longer considers my method "complete". It complains about a missing return statement, even though quickRaise is semantically equivalent to throw (or at least this is what I am trying to do!)
Let me try to reiterate the problem by a reproductive example (this will not compile, which is the problem):
public static void main(String[] args) {
System.out.println(doSomething());
}
public static String doSomething () {
try {
//... Some fun stuff going on here
return "Something";
} catch (Exception e) {
quickRaise("Could not find handshakes");
//throw new RuntimeException("If you uncomment this line, it will compile!");
}
}
public static void quickRaise (String msg) {
throw new RuntimeException(msg);
}
Your idea is highly inadvisable.
For example, this is just bad codestyle:
try {
someIO();
} catch (IOException e) {
throw new RuntimeException("Problem with IO");
}
The reason it's bad is that you have now obliterated the actual information about the problem. That information is locked into 5 separate parts of that exception you just caught: Its type (for example, FileNotFoundException, its message (e.g. "Directory /foo/bar does not exist"), its stack trace, its causal chain, and as throwables are objects, any particular extra detail for that particular kind of exception (such as the DB-engine-specific error coding for some SQLException).
Throwing this info away is silly.
All you'd need to do to fix this, is to add the cause:
} catch (IOException e) {
throw new RuntimeException("IO problem", e);
}
Now the IOException is marked as the cause of the exception you are throwing, which means in error logs you'll see it + the message + the stack trace of it + the stack trace of any causes it had as well.
All you need to do to make the compiler realize that the method ends here, is to throw it:
public static RuntimeException quickRaise(String msg) {
throw new RuntimeException(msg);
return null; // doesn't matter, we never get here
}
// to use:
throw quickRaise(msg);
But, as I explained before, this is a very bad idea.
Secondarily, having the idea of 'I just want to throw an exception and maybe later I want to replace the kind of exception I throw' also doesn't really work out: You need to pick a proper exception for the situation, therefore you cannot write a one-size-fits-all throw method in the first place.
Okay, so what do I do?
Primarily, learn to embrace throws clauses. If your method fundamentally does I/O (for example, the javadoc of it and/or the name makes that obvious, it is for example saveGame(Path p), or scanUserHome), then it should be declared to throws IOException.
If your method is an entrypoint (as in, it is the first point where your own code begins running), then your method should be declared to throws Exception. For example, your public static void main() method should throws Exception. Sometimes an entrypoint isn't main but something else (a webhandler routing hook for example), and sometimes backwards silly franeworks prevent you from doing that, but there tends to be a wrap functionality (such as } catch (Exception e) { throw new ServletException(e); }).
For exceptions which are both [A] fundamentally not part of the method's purpose, but more part of an implementation detail and [B] is very unlikely to go wrong and there's not much you can do other than hard crash if it would, then, yeah, rewrap as RuntimeException. There isn't a lot of point in ever changing this 'globally' for all such exceptions. At best you belatedly realize that failure is a bit more likely than you originally thought and either create a proper exception for it and document this behaviour. But that's, again, on a per-method basis, not something you can apply in blanket fashion.
Your approach is fundamentally at odds with the need for the compiler to see that the flow terminates at the throw statement.
I'd suggest having a utility method that just constructs an exception, which you then throw from the original point.
It's either than or put dummy returns after each call to quickRaise().

Throwing an exception after retrying a block of code

Is it correct, safe and sane to throw an exception after a successful retry? Which programming principle is violated in this example?
class B {
private int total;
public void add(int amount) throws Exception {
if (amount < 0) {
throw new Exception("Amount is negative");
}
total += amount;
}
}
class A {
public B b = new B();
public void addToB(int amount) throws Exception {
try {
b.add(amount);
} catch (Exception ex) {
try {
b.add(-amount);
} catch (Exception ex2) {
}
throw new Exception("Amount was negative. It was inverted and then added.");
}
}
}
your code is working but since you are calling a addToB() method which throws exception inside a catch block you must implement another try-catch block within try-catch block. and at the end you are throwing a exception even after having so many try-catch blocks which is not good since the exceptions if not handled can cause problems and its very bad practise to throw exception if the method was success. i see that you need the user to know what happened inside the method, you can return a string from the
method which will tell the user what happened inside the method.
ex: -
public String addToB(int amount){
String msg = "";
try{
b.add(amount);
msg ="successful";
}catch(Exception ex){
try{
b.add(-amount);
}catch(Exception ex2){
}
msg= "Amount was negative. It was inverted and then added.";
}
return msg;
}
even this is not the best practise bt you might need check this.
There are a few sound principles that you are violating.
Throwing java.lang.Exception is bad in such situations (or in general), even if you are writing toy code. You should consider using a RuntimeException. The idea is pretty simple. You know nothing about the amt until you run the program. If a user or client of this code provides negative argument, then it an unexpected argument only to be known at runtime. Do not promote the Pokemon exception handling anti-pattern.
You are utilizing the baklava code pattern. This should be avoided.
The more serious error you are committing is doing the thing anyway exceptionally or not. Here's a use of your classes:
public static void main(String[] args) {
A a = null;
try {
a = new A();
a.addToB(10); // no exception here, total should be 10
a.addToB(-10);
} catch (Exception e) {
// exception here, but the total should be 20, or not?
System.out.println(a.getTotalFromB());
}
}
Now, in this case, the value of total is 20 even when an exception was thrown! Almost always, exceptions should be used to signal exceptional conditions where the expected things do not happen. This, to me, is a serious violation.
It's possible to do this, but this is a bad idea for three reasons:
You're using exceptions as control flow. This is an antipattern which is to be avoided.
You're throwing Exception. If this is truly exceptional behavior, then you should look to create your own [checked] exception type.
You're catching Exception in that block. If b is null then you're not guaranteed that the input was invalid at all.
Let's start with the flow.
In this scenario, it doesn't make immediate sense why a negative value is considered exceptional enough to recover from, which is what the checked exception implies.
Effectively, if the first attempt seems to fail with a negative number, the idea is to try it again by negating the negative, resulting in a positive number.
Something like this can be mitigated in several ways, depending on what the negative value means to the business:
Throwing multiple exceptions (least preferred)
Silently drop it, but log the value passed in (less preferred)
Throw an unchecked exception and do not require its callers to catch it (preferred)
With my preference, the code above would look like this:
public void add(int amount) {
if(amount < 0)
throw new IllegalArgumentException("Amount may not be negative");
total += amount;
}
This would put the onus of ensuring that the input is correct and appropriate for this method on the developer as opposed to the application. Unit tests here would go a long way to ensure the behavior that you want.
Now, to throwing Exception: Exception is checked meaning that everyone has to catch it or declare it to be thrown, which is unpleasant to code.
Checked exceptions should be reserved for something that the user can do to recover from (for instance, FileNotFoundException - user should be sure that the file path is correct).
Lastly - you should not be catching Exception. That's too broad of an exception to catch, considering that b may be null.

what is the effect that explicits the "throw exception" in the method signature

--the effects of case 1 and 2 are the same, why need to add the exception declaration in method signature?
//case 1
public void doSomething() throws Exception {
//do Something
}
public void Caller() {
try {
doSomething();
} catch (Exception e) {
//handle the exception
}
}
//case 2
public void doSomething() {
//do Something
}
public void Caller() {
try {
doSomething();
} catch (Exception e) {
//handle the exception
}
}
reference:
what is the use of throws Exception
The throws declaration is used to declare which checked exceptions your method throws.
For instance, if I write this code:
public void doSomething() throws SQLException {
}
any code that calls this method must have a try/catch block for SQLException, Exception, or Throwable... or it can have its own throws declaration for one of those 3.
In this case, there is no difference, except that you're alerting the compiler to an exception that you're not going to be throwing.
It's also a bad idea to catch throw "Exception" - in both cases, you want to deal a particular exception that has a particular meaning. When you're catching, the only reason to use a try block is if you expect a particular exception, so you should catch that one. This way, if some unexpected exception comes up, you don't try to handle it the wrong way. (instead, your program fails, and you know there's a condition you have to deal with) When you're throwing, you want to throw a particular exception, either one you make up, or a standard one that has a known meaning, so the calling function knows what to deal with. For example, if your doSomething might throw an ArrayIndexNotFoundException if the widgets are not frobnicated, you might want to catch the ArrayIndexNotFoundException and throw a WidgetNotFrobnicatedException. Any time you throw an exception, your javadoc should specify exactly what circumstances will trigger that issue, so the user of your code has a chance to address this possible failure.
(there is one circumstance when I can see catching Exception, and that's if you want to fade to some graceful halt if things go wrong unexpectedly - in that case, in your catch block you'd log the issue, possibly alert a developer, and throw up some sort of "Sorry, error number 3542 has occurred, please restart the program" message.)
If your doSomething method, has the chance to throw an exception and you don't want to catch it, you should add this throws Exception on the method.
Unless it's an exception that you want to handle immediately in that method, it's good practice to use throws [specific Exception] so that the exception can be handled further up in the code.
It's somewhat commonplace to have a generic Throwable catch at the top that "gracefully crashes" in case something goes wrong.

Is it necessary to use "throws" whenever we use "throw"?

Assuming that the Exception we are throwing is checked, is it compulsory to add throws in a method declaration whenever we use throw inside the method?
Any checked exception (e.g., one which does not extend RuntimeException) that might escape a method needs to be declared in the method signature. For example:
public static void mightThrow(String s) throws NumberFormatException {
// ...
int x = Integer.parseInt(s);
// ...
}
Even though we do not throw any exceptions directly, Integer.parseInt() might throw a checked NumberFormatException. Since we call that method, and we do not catch the potential exception, then our method must also declare the exeception in its throws signature.
This does not necessarily mean that every method that throws (or might throw) a checked exception must declare throws in its signature. If the thrown exception is always caught within that method, it need not be added to the signature. For example:
public static Integer tryParseInteger(final String s) {
try {
return Integer.parseInt(s);
}
catch (NumberFormatException ignored) {
return null;
}
}
In this example, we will always catch any NumberFormatException that might be thrown by Integer.parseInt() and prevent it from bubbling up the stack, so we do not need to declare it in our tryParseInteger() method.
Unchecked exceptions never need to be declared:
public static void unsupported() {
throw new UnsupportedOperationException(
"The specified operation is not supported."
);
}
Here, because UnsupportedOperationException derives from the unchecked RuntimeException, it does not need to be declared.
No, since you may want to throw a exception but handle it in the same place, aka method
The Throws simply let javac know that this method might cause this kind of exception. It is not always necessary. It's useful when you know that a specific method can throw some sort of exception.
Generally speaking, Java is exception-strict, so you have to specific what types of exceptions a method throws. Note that you can use inheritance to simplify your methods' signatures. E.g., you can declare your method as throws IOException, and within its implementation throw any type of IOException you want such as FileNotFoundExeption, InteruptedIOException, etc.
One exception (no pun intended) to this rule are RuntimeExceptions (such as OutOfMemoryError or UnsupportedOperationException) which can be thrown without having to declare them.
Differences:
1) You can declare multiple exception thrown by method in throws keyword by separating them in common e.g. throws IOException, ArrayIndexBoundException etc, while you can only throw one instance of exception using throw keyword e.g. throw new IOException("not able to open connection").
2) throws keyword gives a method flexibility of throwing an Exception rather than handling it. with throws keyword in method
signature a method suggesting its caller to prepare for Exception declared in throws clause, specially in case of checked Exception and provide sufficient handling of them. On the other hand throw keyword transfer control of execution to caller by throwing an instance of Exception. throw keyword can also be used in place of return as shown in below example:
private static boolean shutdown() {
throw new UnsupportedOperationException("Not yet implemented");
}
as in below method shutdown should return boolean but having throw in place compiler understand that this method will always throw exception .
3) throws keyword cannot be used anywhere exception method signature while throw keyword can be used inside method or static initializer block provided sufficient exception handling as shown in example.
static{
try {
throw new Exception("Not able to initialized");
} catch (Exception ex) {
Logger.getLogger(ExceptionTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
4) throw keyword can also be used to break a switch statement without using break keyword.
int number = 5;
switch(number){
case 1:
throw new RuntimeException("Exception number 1");
case 2:
throw new RuntimeException("Exception number 2");
}

Java -- Exception must be thrown, but how?

I am getting an error in NetBeans saying I must throw an SQLException in this method:
private void displayCustomerInfo(java.awt.event.ActionEvent evt)
{
int custID = Integer.parseInt(customerID.getText());
String info = getCustomerInfo(custID);
results.setText(info);
}
This method is created by NetBeans so it is not allowing me to edit the signature and throw the exception. This is why I created the getCustomerInfo() method. This method does throw the exception, because it uses a method to retrieve information from a database about a customer.
public String getCustomerInfo(int cid) throws SQLException
{
Customer c = proc.getCustomer(cid);
// get info
return "info";
}
The getCustomer method also throws the exception and proc.java compiles.
The exact error is
unreported exception java.sql.SQLException; must be caught or declared to be thrown
In general, if your code needs to throw a type of Exception that the signature doesn't support, and you have no control over the interface, you can catch and rethrow as a type the interface does support. If your interface doesn't declare ANY checked exceptions, you can always throw a RuntimeException:
private void displayCustomerInfo(java.awt.event.ActionEven evt)
{
try
{
int custID = Integer.parseInt(customerID.getText());
String info = getCustomerInfo(custID);
results.setText(info);
}
catch (SQLException ex)
{
throw new RuntimeException(ex); // maybe create a new exception type?
}
}
You almost definitely want to create a new Exception type that extends RuntimeException, and have your client code catch that exception. Otherwise, you run the risk of catching ANY RuntimeException, including NullPointerException, ArrayIndexOutOfBoundsException, etc., which your client code probably can't handle.
Read the error message again, it gives you two choices.
You must either declare the exception as thrown (which you cannot do) or catch the exception. Try the 2nd choice.
You need to put a try/catch block around your call to getCustomerInfo(), like so:
private void displayCustomerInfo(java.awt.event.ActionEvent evt)
{
int custID = Integer.parseInt(customerID.getText());
try {
String info = getCustomerInfo(custID);
} catch (SQLException sqle) {
// Do something with the exception
}
results.setText(info);
}
A couple good options for handling the exception might be: logging the exception and the details used to get it, or using it as a signal to retry the connection request. Alternatively, as Outlaw Programmer shows, you could re-throw the Exception as a RuntimeException of some kind, which removes the requirement of checking.
It does not say you must throw it. It says you can catch it. So use a try/catch block and handle it.
try {
...
}
catch (SQLException e) {
System.out.println("Exception happened! Abort! Abort!");
e.printMessage(); //Not sure if this is the correct method name
}
NetBeans generated components have un-modifiable code, and I'm guessing that it is generated as a part of the gui builder. I'd ask if this was the case, but I can't comment yet. If you select a generated object in the GUI editor, on the right there is a tab "code" that can be used to modify the grayed out area of the code.
Here:
I've come across this problem... been puzzled for the past 2 days.. then I open the source (.java file) with sublime, change the code, save, and it works wonders... I'm laughing when I see this works... think outside the box really works...

Categories

Resources