Does throwing exception in JS property assignment in Rhino makes sense? - java

I came across a design that overrides [Scriptable.put][1] in a subclass of ScriptableObject to do some conversion. If the conversion fails the code is throwing an exception. Which means that property assignments like following code can cause a runtime exception to be thrown
aScriptable.dateOfArrival = aVar;
By default rhino wouldn't let the script catch a runtime exception thrown during [Scriptable.put][1]. So catch block in following code will never run:
try{
aScriptable.dateOfArrival = aVar;
}catch(e){
//will not run even if above assignment generates an exception. Script will be terminated instead
}
Overriding ContextFactory.hasFeature() with following code makes the above catch block work:
protected boolean hasFeature(Context cx, int featureIndex) {
if(featureIndex == Context.FEATURE_ENHANCED_JAVA_ACCESS){
return true;
}
return super.hasFeature(cx, featureIndex);
}
My question is that whether the design decision to make property assignment throw exception is correct or property assignments are never supposed to throw exceptions?
[1]: http://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)

IMO it doesn't make sense to throw an exception by design from the put method that JS code can't catch. I think throwing an exception on setting a property is fine, although not that common. Note that JS code can easily reconfigure a property (in ECMAScript 5) with a custom setter that throws.
On the other hand, I think it would be quite surprising if a property getter throws an exception.

Related

Optional IncorrectResultSizeDataAccessException

public Optional<Student> findStudent(String name, String` surname,String nickname)
{
try {
return repository.findOne(predicates.hasSpecifications(name, String surname,nickname));
} catch (IncorrectResultSizeDataAccessException e) {
return Optional.empty();
}
}
the method findOne() throws IncorrectResultSizeDataAccessException if more than one entry is found for the predicate inside of it. Is this the best way to handle the exception thrown? or should the caller handle the exception using something like: optional.orElseThrow()... but this method only handles NoSuchElementException (if no value is present) and not IncorrectResultSizeDataAccessException (If more than 1 RESULT)...
Any ideas guys?
Yeah, this would be the best way to do it.
I'm assuming hasSpecifications is a custom method which returns the id you wish to use to index the database
The thing is "findOne" and "hasSpecifications" are two methods independent of each other.
When we talk about abstraction, in methods then the only things that matter are their input parameters, the return values and the errors that may or may not be thrown.
This means "findOne" only cares about what "hasSpecifications" evaluates to. If there is an error or exception thrown while "hasSpecifications" is still executing then this error abruptly terminates the program (unless caught) and findOne wont even be evaluated (Because it was waiting for the id). A NoSuchElementException cannot be thrown because findOne hadn't started executing yet.
So since it's a custom method, the error handling has to be done by you, as you just did.
To make it more obvious extract predicates.hasSpecifications into a variable on a preceeding line and then place the variable in "findOne"

Application of #Sneaky Throws in lombok

I was playing with the Lombok library in Java and found an annotation called #SneakyThrows.
As the documentation states:
#SneakyThrows fakes out the compiler. In other words, Lombok doesn't wrap or replace the thrown checked exception, but makes the compiler think that it is an unchecked exception.
With other words, this is a way to bypass exceptions at compile time. But in my opinion this should not be the correct way of handling exceptions, because the bypassed exception can show weird behaviour at runtime.
So in which scenario should #SneakyThrows be used?
To add to the existing answers. I personally dislike checked exceptions. See for more info: https://phauer.com/2015/checked-exceptions-are-evil/
To add insult to injury, the code gets bloated when avoiding the checked exceptions. Consider the usage of #SneakyThrows:
List<Instant> instantsSneaky = List.of("2020-09-28T12:30:08.797481Z")
.stream()
.map(Example::parseSneaky)
.collect(Collectors.toList());
#SneakyThrows
private static Instant parseSneaky(String queryValue) {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(queryValue).toInstant();
}
versus non-#SneakyThrows
private static Instant parseNonSneaky(String queryValue) throws ParseException {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(queryValue).toInstant();
}
List<Instant> instantsNonSneaky = List.of("2020-09-28T12:30:08.797481Z")
.stream()
.map(timeStamp -> {
try {
return parseNonSneaky(timeStamp);
} catch (ParseException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
Hence the applicance of #SneakyThrows enables much cleaner code.
I believe the intention here is to cause the compiler to not require a throws whatever Exception to be added to the method declaration.
For example if the method was
public void throwsCheckedException() {
throw new IOException("IO exception thrown");
}
This would cause a compile time exception requiring
public void throwsCheckedException() throws IOException {
throw new IOException("IO exception thrown");
}
The annotation #SneakThrows mitigates this - original method declared as
#SneakyThrows
public void throwsCheckedException() {
throw new IOException("IO exception thrown");
}
This will not cause a compile time error.
Note IDEs might still highlight this as an error, for example in IntelliJ you will need to utilise the Lombok plugin.
I think the documentation is very clear on this:
Common use cases for when you want to opt out of the checked exception
mechanism center around 2 situations:
A needlessly strict interface, such as Runnable - whatever exception propagates out of your run() method, checked or not, it will
be passed to the Thread's unhandled exception handler. Catching a
checked exception and wrapping it in some sort of RuntimeException is
only obscuring the real cause of the issue.
An 'impossible' exception. For example, new String(someByteArray, "UTF-8"); declares that it can throw an UnsupportedEncodingException
but according to the JVM specification, UTF-8 must always be
available. An UnsupportedEncodingException here is about as likely as
a ClassNotFoundError when you use a String object, and you don't catch
those either!
In the JAVA 8 and above when using lambda especially its not an easy way to use.
Consider it mostly for older versions of Java 8.
The purpose itself is to throw an exception deliberately for example for warning. By this the other services/program/code can identify how the request/response flow should be handled. If you already have mechanism in place no need to worry about it.
#SneakyThrows is not of much use in current traditional application development, could be used in some kinda state machine programs where it would be necessary (i do not have expertise in it though) to determine the state of the programs current flow. This is just 1 example of different scenarios there maybe more.

Java NoSuchElementException

So I have a pretty big java application that I wrote a year ago and I'm trying to understand it again. I'm looking at a method in the code where there is an obvious risk of getting NoSuchElementException: I'm calling .next() on a scanner variable that has been constructed with an arbitrary string. The only thing the method is declared to throw are custom made subclasses of Exception. The risky command isn't written in a catch-block either. The code compiles and works fine and when I use my gui in such a fashion that it should throw a NoSuchElementException nothing happens :O
As a test I wrote a catch-block into the code, compiled it, ran the gui and made it throw NoSuchElementException again and the application successfully caught the exception and acted accordingly. How is it that I can compile the code without specifying the this exception may be thrown? If it's any use at all, here is the code without the catch-block:
public static Expression interpret(final Scanner scanner)
throws
InvalidPosition,
NoSuchSpreadsheet,
IllegalStartOfExpression,
InvalidExpression,
FalseSyntax,
InvalidRange {
String keyword = null;
try {
keyword = scanner.next();
} catch (NoSuchElementException e) {
throw new IllegalStartOfExpression();
}
switch(keyword) {
case "Get":
Position pos = PositionInterpreter.interpret(scanner.next());
Expression expression = Application.instance.get(pos);
if (expression instanceof Text) {
System.out.println("Failure");
} else { System.out.println("Success"); }
return new Text(expression.toString());
case "Int":
return new Int(
scanner.nextInt());
As you can see, the method simply assumes that there is more than one word in the scanner after checking if there is at least the one. How am I getting away with compiling this?
It is be cause NoSuchElementException is unchecked exception, which means that it "is-a" RuntimeException which does not force you to catch.
The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes. The Java API defines a number of exception classes, both checked and unchecked. Additional exception classes, both checked and unchecked, may be declared by programmers. See ref for a description of the exception class hierarchy and some of the exception classes defined by the Java API and Java virtual machine.
Runtime exceptions serve the same purpose as checked exceptions; to communicate exceptional conditions (unexpected failures, etc) to the user.
checked exception forces the caller of a method to handle that exception, even if they do not know how to handle it. Often times, developers will end up catching the checked exception, only to re-throw it (or another exception). Hence the Runtime exceptions
Here is the exception hierarchy
As the question has already been answered, I'd like to point on that this is very poor design and not the intended usage of the Scanner class:
try {
keyword = scanner.next();
} catch (NoSuchElementException e) {
throw new IllegalStartOfExpression();
}
What you should really be doing is ask the scanner whether there is any input, and only then retrieving it, like so:
if(scanner.hasNext()) {
keyword = scanner.next();
}
else {
throw new IllegalStartOfExpression();
}
The same applies to the line which is causing your problem:
if(scanner.hasNextInt()) {
return new Integer(scanner.nextInt());
}
java.util.NoSuchElementException is a subclass of java.lang.RuntimeException. RuntimeExceptions don't have to be handled. From the Java API documentation:
RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine.
RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions do not need to be declared in a method or constructor's throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary.

code not throwing exception

I am trying to execute below written code and the code should throw an exception but it isn't doint it
try {
Field.class.getMethod("getInt", Object.class).setAccessible(false);
StringSearch.class.getMethod("searchChars",cc.getClass(),pattern3.getClass()).setAccessible(false);
ss4.getClass().getMethod("searchChars",cc.getClass(),pattern3.getClass()).setAccessible(false);
ss4.searchChars(cc,pattern3);
ss4.searchString(str,pattern);
}
catch(NoSuchMethodException ex){
ex.printStackTrace();
}
it should actually throw IllegalAccessException.
ss4 is an object of class BNDMWildcardsCI (one of the algo for String search)
cc, pattern3 are character arrays
str, pattern are Strings
why it isn't throwing an exception, it is not throwing the NoSuchMethodFound exception means that it is able to find the method also i tried to print the isAccessible and it says false
but when i run the tests it doesn't throw any exception
To the best of my knowledge, if a method is declared public (or otherwise accessible), setAccessible(false) can't make it private. It's only useful if you have a private method and you previously called setAccessible(true).
The method setAccessible(boolean) work on object reflect not on normal object. In your code you set it on a method object not on the ss4 object.
To show my point:
Class<?> clazz = ss4.getClass();
Method searchCharsMethod = clazz.getMethod("searchChars",cc.getClass(),pattern3.getClass());
searchCharsMethod.setAccessible(true);
You have set the accessible flag to false on object assigned to searchCharsMethod not ss4.
As bonus see what happen when you call
searchCharsMethod.invoke(ss4,cc,pattern3);
For more please read the documentation

JUnit4 #Test(expected=MyException.class) VS try/catch

I'm pondering on exception handling and unit tests best practices because we're trying to get some code best practices in place.
A previous article regarding best practices, found on our company wiki, stated "Do not use try/catch, but use Junit4 #Test(expect=MyException.class)", without further information. I'm not convinced.
Many of our custom exception have an Enum in order to identify the failure cause.
As a result, I would rather see a test like :
#Test
public void testDoSomethingFailsBecauseZzz() {
try{
doSomething();
} catch(OurCustomException e){
assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ, e.getFailure());
}
}
than :
#Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
doSomething();
}
when doSomethig() looks like :
public void doSomething throws OurCustomException {
if(Aaa) {
throw OurCustomException(FailureEnum.AAA);
}
if(Zzz) {
throw OurCustomException(FailureEnum.ZZZ);
}
// ...
}
On a side note, I am more than convinced that on some cases #Test(expected=blabla.class) IS the best choice (for example when the exception is precise and there can be no doubt about what's causing it).
Am I missing something here or should I push the use of try/catch when necessary ?
It sounds like your enum is being used as an alternative to an exception hierarchy? Perhaps if you had an exception hierarchy the #Test(expected=XYZ.class) would become more useful?
If you simply want to check that an exception of a certain type was thrown, use the annotation's expected property.
If you want to check properties of the thrown exception (e.g. the message, or a custom member value), catch it in the test and make assertions.
In your case, it seems like you want the latter (to assert that the exception has a certain FailureEnum value); there's nothing wrong with using the try/catch.
The generalization that you should "not use try/catch" (interpreted as "never") is bunk.
Jeff is right though; the organization of your exception hierarchy is suspect. However, you seem to recognize this. :)
If you want to check the raw exception type, then the expected method is appropriate. Otherwise, if you need to test something about the exception (and regardless of the enum weirdness testing the message content is common) you can do the try catch, but that is a bit old-school. The new JUnit way to do it is with a MethodRule. The one that comes in the API (ExpectedException) is about testing the message specifically, but you can easily look at the code and adapt that implementation to check for failure enums.
In your special case, you want to test (1) if the expected exception type is thrown and (2) if the error number is correct, because the method can thrown the same exception with different types.
This requires an inspection of the exception object. But, you can stick to the recommendation and verify that the right exception has been thrown:
#Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
try {
doSomething();
} catch (OurCustomException e) {
if (e.getFailureEnum.equals(FailureEnum.ZZZ)) // use *your* method here
throw e;
fail("Catched OurCostomException with unexpected failure number: "
+ e.getFailureEnum().getValue()); // again: your enum method here
}
}
This pattern will eat the unexpected exception and make the test fail.
Edit
Changed it because I missed the obvious: we can make a test case fail and capture a message. So now: the test passes, if the expected exception with the expected error code is thrown. If the test fails because we got an unexpected error, then we can read the error code.
I came across this when searching how to handle exceptions.
As #Yishai mentioned, the preferred way to expect exceptions is using JUnit rules and ExpectedException.
When using #Test(expected=SomeException.class) a test method will pass if the exception is thrown anywhere in the method.
When you use ExpectedException:
#Test
public void testException()
{
// If SomeException is thrown here, the test will fail.
expectedException.expect(SomeException.class);
// If SomeException is thrown here, the test will pass.
}
You can also test:
an expected message: ExpectedException.expectMessage();
an expected cause: expectedException.expectCause().
As a side note: I don't think using enums for exception messages/causes is good practice. (Please correct me if I'm wrong.)
I made catch-exception because I was facing the same problem as you did, Stph.
With catch-exception your code could look like this:
#Test
public void testDoSomethingFailsBecauseZzz() {
verifyException(myObj, OurCustomException.class).doSomething();
assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ,
((OurCustomException)caughtException()).getFailure() ;
}

Categories