Will it throw an exception if it is null? - kotlin

I am pretty new Kotlin world and do not understand the following code snippet:
#GET
#Path("/env/{id}")
fun read(#PathParam("id") id: EnvStageId): Uni<Environment> =
createUni(repo.read(id)).map {
it ?: throw WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
.type(TEXT_PLAIN)
.entity("Environment $id does not exist")
.build())
}
The question is, if it is null it will then throw an exception right?

The elvis operator ?: is not null or the continuation.
Yes. If it is null then it will throw an exception.
The thing is, sometimes it is better to crash: if that operation is supposed to always return something from the local db, then if it fails you get an alert that there is something very bad going on, crashalytica for prod are standard this days.
Maybe the design is exceptions throwing exceptions on low level implementations. I do not think so, because that seems to be mixing network with repository, so I will doubt it. But on the other hand it seems to be so, because someone wrote an special exception for that, if it so, then the next architecture layer should catch those exceptions and handle them gracefully.

Related

kotlin singleton exception is bad or good?

i'm studying kotlin.
I have a question about using exception.
which is better to use object exception or class exception in kotlin?
object CustomDuplicateId : RuntimeException("Invalid user with Id")
class CustomDuplicateId : RuntimeException("Invalid user with Id")
if im using this exception only one location, than stacktrace is always same.
so i think... it doesn't need to use class. is it right?
or is it bad to use singleton exception?
can anyone let me know what's better code to write exception?
There are multiple reasons why it's incorrect to use object.
the stacktrace is wrong in several ways:
It's created at instantiation time, so you'll see <clinit> as first line in the stacktrace because it's created when initializing the object's class for the first time
Even if you throw it from the same place, it won't necessarily be when called from the same caller, so the bottom (root) of the stacktrace will be incorrect if this exception is thrown multiple times across the life of your application
technically the exception class has mutable parts and it would be dangerous/incorrect to allow user code to tamper with this. A very concrete example of this is that user code could add suppressed exceptions to your exception instance (which would only be valid for one throw and yet persist in your object). This is technically a memory leak.
it's likely you would need different messages with more information about why it was thrown (in that case the duplicate ID is very much needed) - so you need different instances with different data anyway
you might throw it from different places in the future (even now in tests/mocks maybe?), and in that case the stacktrace would be even more wrong
independently of technicalities like the above, class vs object also sends a message to the reader that is a bit unclear - why an object here? This exception is not inherently unique. It just so happens that you throw it in one specific place right now and rely on the stacktrace being the same.
Here is an example for the major issue (#1):
object MyExceptionObject : RuntimeException("boom")
fun main() {
try {
caller1() // line 7
} catch (e: Exception) {
}
caller2() // line 10
}
fun caller1() = doStuff() // line 13
fun caller2() = doStuff() // line 14
fun doStuff() {
throw MyExceptionObject // line 17
}
The caller1() throws the exception but that one is caught. The caller2() throws the exception again and that one is not caught. The stacktrace we get for the uncaught exception incorrectly shows the caller 1 (with lines 7 and 13) but the correct one should be caller 2 (with lines 10 and 14):
Exception in thread "main" com.example.MyExceptionObject: boom
at com.example.MyExceptionObject.<clinit>(ExceptionObjectExample.kt)
at com.example.ExceptionObjectExampleKt.doStuff(ExceptionObjectExample.kt:17)
at com.example.ExceptionObjectExampleKt.caller1(ExceptionObjectExample.kt:13)
at com.example.ExceptionObjectExampleKt.main(ExceptionObjectExample.kt:7)
at com.example.ExceptionObjectExampleKt.main(ExceptionObjectExample.kt)
All in all, just use a class.

How to do a fail fast in Kotlin properly?

I want to fail fast if a specific function is returning null. I have no case where default value would make processing meaningful.
This is the snippet:
val entityAttributes = entity.optJSONObject("Attributes") ?: run {
LOG.error("Could not find 'Attribute' entry in Entity object")
return
}
So if entity.optJSONObject("Attributes") returns null (which it does desipite the opt*) I want to escape from the function scope.
Is the way I did it the proper one? I am fairly new to Kotlin and want to get used to the proper ways of doing these things as early as possible.
You can return from the function early like you do above. If your function returns something besides Unit, then you'd have to return some default value.
Throwing an exception allows you to exit a function without returning anything, but the exception will crash the program if you don't catch it somewhere. Sometimes this is exactly what you want to happen if the error is something that should never happen, because then you'll catch it during testing and be able to fix it before releasing your application.
Use the global error(cause: Any) function and it will immediately throw an IllegalStateException.

How to find what exception some library code might throw

I am new to Kotlin and I have the following problem: In my project I am using a small library (JAR, no sources). In it there are few custom exception classes defined which inherit Exception class. Some methods throw these exceptions.
In my code I bump into the problem that I don't know what exception the library code might throw so I can catch it and thus sometimes the exception goes trough the roof.
What it is the usual way to handle such situations in Kotlin?
Normaly such exceptions should be declared in the documentation of the library that you are using (either the JavaDoc, KDoc, or a website). There is no structured way to get all exceptions a function can throw, other than decompiling the code and step through it yourself. (by using the build in decompiler, that jet brains ship in IntelliJ for example)
You could also catch all exceptions, but I would always argue, that this is not a good decision in almost all cases.
I don't exactly know the right approach in kotlin, but you may use the following idea from scala:
Try -
try Success(r) catch {
case NonFatal(e) => Failure(e)
}
If exception is not fatal:
case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable => false
case _ => true
then just return Failure(e) otherwise throw it.
How can you use it? At least you will not end up like this:
try {
...
} catch {
case _ : Throwable => ... // catch all exceptions
}
Yes, you still don't know which exceptions code may throw, but using this approach you can control the general execution flow.
But of course, it will be much better if docs list exceptions which may be thrown.

Ignoring Exceptions in Object Oriented Programming

In some applications, I came across some lines of code which deliberately eats the exceptions. In my application the benefit of doing this is - To ignore the exception and just continue with the loop(The exception handled is for an error thrown inside the loop). The following lines of code looks evil to even an experienced developers. But is sensible to the context(I mean, that is the requirement - to process all the files in the directory).
try{
//some lines of code which might throw exception
}catch(Exception e){
//no code to handle the error thrown
}
What other benefits can ignoring exceptions provide?
If it is a requirement to process all the files, if you get an exception during processing one of them, is not the requirement broken already? Either something failed or the exception is not needed.
If you want to continue the processing handle the exception, then continue. Why not just report the problem with processing a given file,so someone can later process it manually? Probably even stupid cerr << "Hey I had trouble with this file '" << file <<', so I skipped it.\n" would be better than nothing.
Exception is there to signal something. If you are ignoring it either you are doing something nasty, or the exception is not needed.
The only valid reason for ignoring the exception I can think of is when someone throws exceptions at you for no good reason. Then maybe, yeah, ignore.
This is generally the mark of bad code - you always want to handle your exceptions by at a minimum reporting what the exception is. Ignoring exceptions will let your program keep running, but generally exceptions are thrown for a reason and you or the user need to know what that reason is. Doing a catch-all and escaping just means the coder was too lazy to fix whatever problems cropped up.
The exception is if the coder is throwing exceptions merely to pass arguments, which is something I saw on DailyWTF once.
Usually we should not absorb the exception but there can be reason like there is a function which is out of business logic that is just to help some kind of extra functionality, then you do not want your application to break if that function throw the exception in that case you absorb/eat the exception. But I do not recommend the empty catch block, one should log this in ELMAH or other error logging tools for future.
I don't think there any any benefits of ignoring exceptions. It will only cause problems. If you want the code to be executed in the loop, after handling it, it will continue with the loop because exception is handled. You can always process the files in your directory even if you are not doing anything after handling exceptions.
It will be better if you write some log regarding the files for which exception is thrown
If you eat the exception. You may never know what is the actual cause of the problem.
Considerr this example
public class Test {
private int x;
public void someMethod(){
try {
x = 10/0;
} catch (Exception e) {
}
}
public static void main(String[] args) {
Test test = new Test();
test.someMethod();
System.out.println(test.x);
}
}
This will print simply 0 the default value of x as exception occured during division and value was not assigned to x
Here you are supposed to get actual result of the division. Well it will definitely throw an ArithMeticException because we are dividing by zero and we have not written anything in catch block. So if the exception occurs, nothing will be printed and value of x will be 0 always and we can't know whether the division is happend or not. So always handle exceptions properly.

Proper use of try .. catch

Should I be using this method of throwing errors:
if (isset($this->dbfields[$var])) {
return $this->dbfields[$var];
} else {
throw new FieldNotFoundException($var);
}
or this style:
try {
return $this->dbfields[$var];
} catch (Exception $e) {
throw new FieldNotFoundException($var);
}
...or something else altogether?
quick explanation of the code: $this->dbfields is an array. isset() checks if a variable is set, in this case, whether the array element exists.
The second example is bad. You're taking a lot of overhead to catch an exception when, as you demonstrate, it's just as easy to prevent the exception in the first place. Plus you also assume you know why that exception was thrown - if there was some other exception, like say an out of memory or something, you're reporting it as a "field not found" even if it wasn't.
Keep in mind that try/catch in languages like C++ and Java are very expensive because of all the state they have to save and restore. Python, on the other hand, has very cheap exceptions and they positively encourage you to use a try/except for simple validation. But even so, catching everything and pretending it's one type of exception is still bad.
//First let's do the checks.
if(!isset($this->dbfields[$var]))
throw new FieldNotFoundException($var);
//Now we're in the clear!
return $this->dbfields[$var];
Catching "Exception" is not, most of the time, considered a good practice, out of the two you displayed, I would use option 1.
Catching all exceptions may hide a different exception and mask it as a FileNotFoundException.
I prefer the first one, but if dbfields[$var] throws something reasonable when you access a non-existent element, then I'd prefer just returning it without checking.
I don't particularly like changing the exception type unless I have a good reason -- also if you do, make sure to try to preserve the original exception and stack trace.
Just re-read your explanation.
I guess your method there in #1 is going to catch any exceptions that might be thrown and simply return a bool. I definitely don't like the catching of the generic exception most of the time, so #2 wouldn't be my choice.
"...or something else altogether?"
Neither is very good, so something else would be appropriate.
Fix version 2 to catch the correct exception, not every possible exception. Post that as option 3. I'll upvote something that catches a specific exception instead of Exception.
This is far from language-agnostic.
Some languages won't throw errors for accessing non-existant fields, and the preferred pattern depends a lot on the implementations of the arrays, tables, objects, etc.