Consider adding jOOL-like Syntax
I have been using this library for quite a while, and I can't recall one place where I didn't use Exceptions.sneak()#method.
Consider this example:
List<Path> nonEmptyFiles = Files.list(somePath)
.filter(path -> Exceptions.sneak().get(() -> Files.readString(path)).isEmpty())
.toList();
The filter is ugly and takes too much time to understand for its purpose.
My suggestion is to allow users to choose their preferred ExceptionHandler - so 99% of the time the syntax is clearer and shorter:
.filter(path -> Unchecked.get(() -> Files.readString(path)).isEmpty())
P.S: I know the example can be rewritten using map/filter, but it still feels like too much...
.map(Exceptions.sneak().function(Files::readString))
.filter(not(String::isEmpty)
Cannot you do this using static imports?
import com.machinezoo.noexception.Exceptions.sneak;
var nonEmptyFiles = Files.list(somePath)
.filter(path -> sneak().get(() -> Files.readString(path)).isEmpty())
.toList();
Eclipse will suggest configured static imports and I guess other IDEs would too. This would work for any exception handler, including custom ones. You could go further and create utility function for Exceptions.sneak().get(). I use static imports extensively in my code, including for common exception-handling patterns.
While I could easily generate static versions of the predefined exception handlers, there are two problems with that. Firstly, it would work only for select few handlers. Secondly, I would have to allocate more single-word class names, which risks conflicts with other code.
That said, I am myself using Exceptions.sneak() a lot too, so perhaps I could provide Sneak class and perhaps a few others, probably as an add-on library, so that I do not pollute class namespace for everyone.
Cannot you do this using static imports? ... I use static imports extensively in my code, including for common exception-handling patterns.
While I'm always in favour of static import where it improves the readability(Collectors is a great example), I find it problematic in the case of sneak() because:
.filter(path -> sneak().get(() -> Files.readString(path)).isEmpty())
is not clear - it requires me and the other devs to recall what "sneak" means.
On the other hand, jOOL's Unchecked.consumer() is so clear that static import ruins it.
While I could easily generate static versions of the predefined exception handlers, there are two problems with that. Firstly, it would work only for select few handlers.
I didn't say that you would create multiple classes - just one that delegates to a chosen handler. I don't know how the library works deeply behind the scenes, but what do you think about this implementation? Currently I have to copy paste that class per project and that just sucks.
Secondly, I would have to allocate more single-word class names, which risks conflicts with other code.
Well that can always happen with any class - that's why import statements exist.
Specifically, AFAIK there is no JDK class named Unchecked and I think it's such a rare class name that your concern is negligable.
.filter(path -> sneak().get(() -> Files.readString(path)).isEmpty())is not clear - it requires me and the other devs to recall what "sneak" means. On the other hand, jOOL's
Unchecked.consumer()is so clear that static import ruins it.
If the name "sneak" is a problem, you can always define your own unchecked(), handler(), or exceptions().
I didn't say that you would create multiple classes - just one that delegates to a chosen handler. I don't know how the library works deeply behind the scenes, but what do you think about this implementation?
Such global overrides are tricky. Where are you going to initialize it? In main()? How do you run unit tests then? How do you run JMH benchmarks? What if some app code is promoted to library code and cannot rely on app initialization anymore? What if some code runs before main(), for example initialization of main()'s class and its dependencies?
Indeed, globally accessed variables are strong indicators of bad design, unless we're in the rare case where global access is the concept.
The class I proposed is just an addition - another dev can continue calling Exceptions.sneak().method() without a problem, the class is for those who do want to improve the syntax due to heavy/ugly usages of the library.
Regarding the trickyness: Exactly like how Thread#setDefaultUncaughtExceptionHandler is used for global logging, if a dev desires to override the default handler - they can do that in main as well.
Also, all popular unit testing frameworks allow you to run code before invoking any tests.
Last thing I want to say that it's alright if you decide to not add such a class, the library is good enough for most usages 👍🏻
I have been thinking about this and the global override is too much of a risk. It would encourage people to write bad code that fails unexpectedly and it would be all blamed on noexception. People who want it can approximate it using static imports. I will nevertheless consider fixed-function global classes as a possible future extension.
Yeah, I just wrote the simplest(and actually the only) code I had on mind. I'm glad that you acknowledge the syntax problem at certain usages, that's what I wanted, and I'll be waiting to see your own solution.
Thank you!
Reopened for future updates if needed.