Why does `ScopedValue.where(SCOPE_VALUE, val).call()` throw Exception?
Kasper Nielsen
kasperni at gmail.com
Fri Mar 24 11:15:17 UTC 2023
On Fri, 24 Mar 2023 at 09:59, Andrew Haley <aph-open at littlepinkcloud.com> wrote:
> Surely you could write something like
>
> public static <T> T call(ScopedValue.Carrier aCarrier, Callable<T> aCallable) {
> try {
> return aCarrier.call(aCallable);
> } catch (RuntimeException e) {
> throw e;
> } catch (Exception e) {
> throw new UndeclaredThrowableException(e);
> }
>
> ... and then use it everywhere as
>
> return call(ScopedValue.where(s, value), callable);
>
> ... or even wrap the ScopedValue.Carrier class to give you exactly what you need.
>
Sure, it will probably end up in a reusable class somewhere.
I just tested it out in a couple of separate small projects that
didn't share any code. And most of the places I didn't have any
need for the checked version. Just posting my observation.
Regarding the issue on handling of Throwable instead of plain Exception.
This still feels a bit clunky if you are unable to handle it inside the scope.
What I got is
interface ThrowingSupplier<R> { //Could be <R,T extends Throwable>
R get() throws Throwable;
}
public static <T, R> R where(ScopedValue<T> key, T value,
ThrowingSupplier<? extends R> op) throws Throwable {
record Result<R>(R result, Throwable failure) {}
Result<R> result = ScopedValue.where(key, value).call(() -> {
try {
return new Result<>(op.get(), null);
} catch (Throwable e) {
return new Result<>(null, e);
}
});
if (result.failure != null) {
throw result.failure;
}
return result.result;
}
It is definitely doable but doesn't feel right.
/Kasper
More information about the loom-dev
mailing list