I have another question regarding checked exceptions. I have attempted to answer the question below.. Below my attempt is the original question and code. Could you let me know if I'm right or how I can change my attempt to make it correct. Kindest regards
public boolean checkMembership(MemberId memberId)
{
// Firstly the method is tried to see if it works.
try {
public boolean checkMembership(MemberId memberId)
}
// If it does not work, then the exception is called
catch (InvalidMemberIdException ex){}
}
The checkMembership method is part of the Membership class. Its purpose
is to validate the memberId it is passed as its parameter and then try to find it
in a list of members. It returns true if the memberId is found and false if not.
public boolean checkMembership(MemberId memberId)
{
if (!validate(memberId)) {
// An exception must be thrown.
…
}
// Further details of the check membership method are omitted.
…
}
If the memberId parameter to checkMembership is not valid then an
InvalidMemberIdException must be thrown. Rewrite the part of the
checkMembership method shown above to show how this would be done.
Remember, this is a checked exception. You must include detailed javadoc
comments for the method that conform to good stylistic conventions.
just add a
throw new InvalidMemberIdException("the id was invalid");
and update the javadocs.
edit -- i noticed them method as written is calling itself recursively (within the try catch block). You probably dont want to do this. Also, in the catch block you don't want to do nothing ('swallowing the exception' is usually bad). Put a log in there or something, or a comment that you are intentionally not doing anything.
Related
Usually when writing a public method I do some error checking e.g.
public SomeResult processSomething (int i, List<String> items) {
if( i < 0 ) {
throw new IllegalArgumentException();
}
if(items == null) {
throw new NullPointerException();
}
etc
}
In android programming what is the standard approach for this? I noticed that when a fragment crashes the emulator goes to the previous fragment so from behavior shown to the user I guess it is ok. But what is the best way to deal with exceptional/error conditions?
The best practices here would be very similar to those used elsewhere in the Java world:
1. The first lines of a method are usually devoted to checking the validity of method arguments. The method should fail as quickly as possible in the event of an error.
When validating an argument, an Exception is thrown if the test fails. It's often one of these unchecked exceptions that are thrown:
IllegalArgumentException
NullPointerException
IllegalStateException
These are all derived from RuntimeException.
2. If every object parameter of every method in a class needs to be non-null in order to avoid throwing NullPointerException, then it's acceptable to state this once in the general class javadoc, instead of repeating it for each method.
References:
Preconditions, Postconditions, and Class Invariants.
EDIT:
To answer your question about "view specific for errors": while it is certainly possible to do that, the idea is that an Exception indicates the presence of programming errors in the code. Therefore, apps should be allowed to crash so that the user can report the error, and the developer thereby gets the error logs from the app's Play Store account. This way he can correct the sources of those errors. The process should continue till, hypothetically, the app is completely free of errors.
Nowadays we can use Kotlin Preconditions.kt:
data class User(val active: Boolean, val email: String?)
class UserHelper (private val user: User) {
fun mergeUsers(otherUser: User) {
// To verify enclosing class state we use "check methods".
// If check fails IllegalStateException will be thrown
checkNotNull(user.email) { "user email is null" }
check(user.active) { "user is not active" }
// To verify argument we use "require methods".
// If check fails IllegalArgumentException will be thrown
requireNotNull(otherUser.email) { "otherUser email is null" }
require(otherUser.active) { "otherUser is not active" }
// All the preconditions has been meet, so we can merge users
// ...
}
}
I've got some problems trying to make the only common exception for my whole class. Could somebody tell me how make that? Before that I tried to make little try-throw-catch blocks like that:
try {
Integer a = 10;
if(a == 10)
throw(/*what to write here?*/)
}
//some code later... or here must be NO code because catch goes right after the try(if I'm not mistaken)?
catch(/*what to write here?*/){
System.err.println("smth gone wrong");
}
So the question is how to create one big exception for whole class and how to make correctly example above?
You need to define an Exception that you want to throw, specify that a method in your class throws it, and then catch that Exception when you try that method. Exception throws are not defined at a class-level, though - they are defined per-method.
See Oracle's Documentation On Throwing Exceptions for more details.
I have a class Game with a constructor with the following signature:
public Game(String[] boardState) throws InvalidStringsInputException, WrongNumberOfMarksException
And there is a method in junit4 testcase:
public static Game newGameFromStringsSuccessful(String[] input) //it is the line 9
{
try
{
return new Game(input);
}
catch (WrongNumberOfMarksException exception)
{
fail("Caught exception where it shouldn't be");
}
catch (InvalidStringsInputException exception)
{
fail("Caught exception where it shouldn't be");
}
}
I am using eclipse and it shows me an error:
This method must return a result of type Game line 9 Java Problem
If I insert return null in the ends of both catch blocks, the error disappears, but my question doesn't: why does java want it even after fail() method is called?
why does java want it even after fail() method is called?
Because the compiler doesn't know that fail can't return normally. There's no way of expressing that within Java. The end of the fail message call is still reachable - so the end of the method is also reachable.
Suppose there was a bug in the fail method, so you ended up reaching the end of the method - what would you expect to happen?
The simplest fix for this is to throw some runtime exception at the end of the method, e.g. AssertionError:
throw new AssertionError("fail must have returned normally!");
It's basically an exception to say "The world is crazy, I don't want to live here any more" - which also keeps the compiler happy, as the closing brace of the method is no longer reachable.
Another alternative - not available here, as you don't control the fail method - would be to declare the fail method to return some kind of runtime exception, at which point your catch blocks could look like this:
catch (InvalidStringsInputException exception)
{
throw fail("Caught exception where it shouldn't be");
}
Of course the implementation of fail would still be to throw an exception rather than return it, but it means the compiler knows that that catch block is definitely not going to complete normally.
Jon's answer below explains why the compiler is complaining. However, I suggest that the correct way to avoid this is to not have the try/catch in you test. Just let the exception propagate up the call stack and out of your test. JUnit will catch it and fail the test while providing the entire stack trace of where the exception was thrown.
Or if you prefer not to have to propagate the throws clause, wrap the exception in a RuntimeException and then throw that. Again, this will provide the stack trace to allow for better diagnosis.
In my unit test, I test a method for an expected RuntimeException and I want to distinct those thrown by my component from ones thrown by the code called in the method.
Creating a custom exception type is unnecessary and does not solve the problem if the method throws the same exception type but for different reasons, e.g. InvalidArgumentException.
Looks like the only way to tell them is the message or the error code. Because the message can be changed during development, the error code seems the only reliable option.
What is the best practice for creating of system of error codes so they don't conflict with ones of external packages, eg. third party libraries?
Creating a custom exception type is unnecessary and does not solve the
problem if the method throws the same exception type but for different
reasons, e.g. InvalidArgumentException.
Why do you think it's unnecessary? This is what you should do. Derive your own custom exception classes, throw their instances from your code and catch them outside (in your unit tests). The catch statement can be repeated in anticipation of multiple different exception classes:
try {
// something
} catch (MySpecificException e) {
// you know that your code threw this
} catch (Exception e) {
// this is coming from somewhere else
}
--Edit--
Sorry, I didn't see the java tag. Even though the following example uses PHP constructs, the principles should still apply.
--Original--
I use custom exception codes in only a few, very specific cases, and I store these codes in a custom exception class which extends the default exception class. They are stored in the class as constants, as the value doesn't really matter, but the context does.
Consider:
class CoreLib_Api_Exception extends Exception
{
const EXCEPTION_FORMAT = '%s (%s): %s';
const CODE_FILE_DNE = 100;
const CODE_DIR_BASE_EQUALS_REMOVE = 101;
const CODE_XML_READER_UNABLE_TO_OPEN = 200;
const CODE_XML_READER_UNABLE_TO_READ = 201;
}
// Example usage
class CoreLib_Api_Reader
{
protected function getReader()
{
$reader = new CoreLib_Api_Xml_Reader();
if (!#$reader->open($this->getFileUri())) {
$e = new CoreLib_Api_Exception(sprintf('Could not open %s for parsing', $this->getFileUri()), CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN);
throw $e;
}
}
}
// Calling code
try {
$reader = CoreLib_Api_Reader();
$reader->setFileUri($fileUri);
$reader->getReader();
} catch (Exception $e) {
// If code is anything other than open, throw it
if ($e->getCode() !== CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN) {
throw $e;
}
$e = null;
$reader = null;
}
By using the exception code, I can check to determine if the reader is unable to open the file, if so ignore the exception and move on, otherwise throw the exception and break the flow.
And if one of my exception codes collides with a third party exception code, it doesn't matter, as I mentioned before, using constants, the context will dictate which code I want to match on.
I test a method for an expected RuntimeException
I think this is a mistake. A RuntimeException should be used only for indicating bugs in the code that the code itself can detect. Testing should test only for specified (defined) behaviour. But when there is a bug in some code, its behaviour is undefined (who knows where the bug could be or what it might do). So there is no point in trying to specify what RuntimeExceptions some code should throw; that is like specifying how the code should behave "in the presence of a bug". Throwing particular RuntimeExceptions with particular messages should be seen as a courtesy to the maintenance programmer (who is likely to be you).
I have a fairly standard creational pattern whereby a class exposes a static method for returning instances of itself, like so:
public class MyClass {
private MyClass(/*parameter list*/) {
// internal construction
}
public static MyClass GetMyClass(/*parameter list*/) {
return new MyClass(/*parameter list*/);
}
}
...
//this line wont break in the debugger and seemingly never gets called - why?
MyClass inst = MyClass.GetMyClass(/*parameter list*/);
However, inst is always null. I can't break on the line that calls the static method, the debugger just ignores it - what's going on?
Edit: Thanks for the suggestions.
All projects have been cleaned and rebuilt (manully in NetBeans)
I have added a break in the static method and no it isn't hit.
Yes, the code above is being called (ultimately) in a constructor for a Swing 'FrameView' though it surely shouldn't matter where I am calling this from, should it?
There is no exception swallowing anywhere
Side note, other than the missing class declaration (which was a typo) why is this not valid Java? Why is this obviously C# code? Explanations would be more helpful than downvotes :)
Edit II: The Params is just supposed to indicate a whole load of parameters - sorry if this confused anyone, I obviously know parameters have type declarations and so on, the code above was intended as a quick shorthand version rather than a full and (complicated) real sample...
A couple of options:
An exception is being thrown which you're somehow missing
You're not debugging the code that you think you are (i.e. your built code is out of date with your source code)
The latter is the most likely one, IMO.
Apparently you're swallowing an exception inside the constructor something like:
try {
// Something.
} catch (Exception e) {
}
You should never do that. It makes debugging and nailing down the root cause much harder. Rather throw it or at least do a e.printStackTrace(). If throwing and you don't want to use the throws clause for some reasons, consider using a RuntimeException (or one of its subclasses). E.g.
try {
// Something.
} catch (Exception e) {
throw new RuntimeException("Construction failed.", e); // Try to be more specific, e.g. IllegalArgumentException or so. Or just write robust code, i.e. nullchecks and so on.
}
or (but in my opinion not very applicable in your case):
try {
// Something.
} catch (Exception e) {
e.printStackTrace();
}
I understand that you are trying to make a simple example to show your problem, however if you add the appropriate type statements into your sample code, then it both compiles and does what you expect.
However, in your original codebase you could simply place the breakpoint in the static method to see whether or not it is called.
Maybe a simple question, but you never know… are you sure that you are running the code that you think you are running? That is, is everything recompiled and built from the latest sources?
There is nothing wrong with :
MyClass inst = MyClass.GetMyClass(Params);
It depends what is before or after that line of code.
Start by doing this:
public class MyClass
{
private MyClass(/*parameter list*/)
{
System.out.println("entering MyClass(...)");
// internal construction
System.out.println("leaving MyClass(...)");
}
// Java uses lower case for method names - so get not Get
public static MyClass getMyClass(/*parameter list*/)
{
final MyClass foo;
System.out.println("entering getMyClass(...)");
foo = new MyClass(...);
System.out.println("leaving getMyClass(...)");
return (foo);
}
}
...
MyClass inst = MyClass.getMyClass(/*parameter list*/);
See if outside the debugger the code gets called.
If you are catching any exceptions, at the very least do:
catch(final WhateverException ex)
{
// at the very least do this so you can see that the exception happens
ex.printStackTrace();
}
Avoid catching Throwable, Error, Exception, and RuntimeException. Infact the best way do do it is get rid of all the catch statements and then only add catches for what the compiler tells you that you have to have.
The other thing is you do not say where MyClass inst = MyClass.getMyClass(/parameter list/); is called from. It is entirely possible that that line never gets hit.
You mention that you're calling this from the constructor of a FrameView, but I assume you're talking about an implementation or extension of that interface/object. My reasoning was to make sure you wern't recursively invoking the constructor.
I think the reason why catching java.lang.Exception isn't catching the problem is because it is likely too specific in this case. Try catching java.lang.Throwable which will catch errors like java.lang.NoClassDefFoundError - that frequently crops up when you have a jar missing somewhere.