It is not (only) about throwing exceptions in case no suitable adapter is 
available. It rather is about the fact, that today the adaptTo is a barrier for 
all kinds of exceptions. In some cases the adaptation fails for a specific 
reason (one example is Sling Models where injection fails, another one is the 
issue mentioned in https://issues.apache.org/jira/browse/SLING-2712 (ValueMap 
not supporting primitives)). Both would be valid use cases where the client 
would be interested to catch the exception here.

On 01 Jul 2014, at 10:34, Carsten Ziegeler <cziege...@apache.org> wrote:

> Adding a new interface would require us to implement it all over the place
> and as Felix points out, client code would always need to check whether the
> new interface is implemented or not Having to methods, like hasAdapter and
> adaptOrThrow does not work very well as between the two calls things might
> have changed already: while hasAdapter returns true, the underlying factory
> gets unregistered before adaptOrThrow is called.
> In many use cases, the current pattern works fine - the client does not
> care whether an exception is thrown within the adaption - it just cares
> whether an object is returned or not. And there are valid use cases, where
> client code does different things whether the adaption works or not (e.g.
> the post servlet checks for adaptTo(Node) and then does additional things
> if the resource is backed up by a node.)
> 
> I see the point that there are also use cases where it would be fine to
> simpy throw an exception if adaptTo is not successful. This would make the
> client code easier. However as this most properly is a runtime exception,
> client code can today just call a method on the object and end up with a
> NPE - having the same result :)
> 
> This leaves us with use cases where the client code explicitely wants to
> catch the exception and then do something depending on the exception. Maybe
> we should just add something for this explicit use case instead of bloating
> the general adaptTo mechanism?
> 
> Regards
> Carsten
> 
> 
> 
> 
> 2014-07-01 9:44 GMT+02:00 Konrad Windszus <konra...@gmx.de>:
> 
>> Regarding 1) Having such a Result class would mean that all consumer would
>> need to unwrap the exception first. So instead of being forced of
>> implementing a null-check (as with the old solution) one would need to
>> implement another check. I want to prevent such a burden to the consumers.
>> Regarding 2) Since the client code knows on which object the
>> adaptToOrThrow is called I don’t get why an instanceof check is necessary.
>> Whether this object implements Adaptable2 is known at compile-time, so you
>> do have the full IDE-support here.
>> Regarding 3) In that case I would no longer allow a null value to be
>> returned. One drawback is, that all the null checks are no longer effective.
>> 
>> IMHO solution 2) is the best. At the same time I would deprecate the old
>> Adaptable, because I cannot come up with a real use-case where returning
>> has an advantage. I would rather implement another method boolean
>> hasAdapter(Class<AdapterType> type) on the Adaptable2 interface.
>> Regards,
>> Konrad
>> 
>> On 01 Jul 2014, at 09:07, Felix Meschberger <fmesc...@adobe.com> wrote:
>> 
>>> Hi
>>> 
>>> There currently are two issues floating around dealing with the question
>> of returning more information than just null from the
>> Adaptable.adaptTo(Class) method:
>> https://issues.apache.org/jira/browse/SLING-3714 and
>> https://issues.apache.org/jira/browse/SLING-3709. I think these requests
>> warrant some discussion on the list.
>>> 
>>> Background: adaptTo can be implemented by Adaptable implementations
>> themselves or, by extending from SlingAdaptable, they may defer to an
>> AdapterMananager. AdapterManager itself is extended by AdapterFactory
>> services. All these interfaces define an adaptTo method. All these methods
>> return null if adaption is not possible and don't declare or document to
>> throw an exception.
>>> 
>>> While not explicitly documented as such, the intention is and was that
>> adaptTo never throws on the grounds that adaption may fail which is
>> considered a valid result and thus exceptions are not to be expected and
>> handled.
>>> 
>>> Hence all implementations of the methods generally
>> catch-and-log-but-don't-throw. Interestingly SlingAdaptable.adaptTo and
>> AdapterManagerImpl.getAdapter don't catch — so any RuntimeException thrown
>> from an AdapterFactory would be forwarded.
>>> 
>>> Having said this there are options available:
>>> 
>>> (1) Add support for a new Result<?> class. We would probably implement
>> this in the AdapterManager.getAdapter implementation explicitly handling
>> this case because it would entail catching the adaptTo/getAdapter calls to
>> get the exception (the Result.getError should return Throwable probably not
>> Error)
>>> 
>>> Use would be limited to new AdapterFactory implementations throwing
>> RuntimeExcpetion. For Sling Models this would be the case.
>>> 
>>> (2) Add a new adaptToOrThrow method, which is declared to throw a
>> RuntimeException and never return null: Either it can adapt or it throws.
>> This would require a new interface Adaptable2 (probably) to not break
>> existing Adaptable implementations. The SlingAdaptable base class would
>> implement the new method of course, probably something like this:
>>> 
>>>> SlingAdaptable implements Adaptable2 {
>>>> …
>>>> public <AdapterType> AdapterType adaptToOrThrow(Class<AdapterType>
>> type) {
>>>>     AdapterType result = this.adaptTo(type);
>>>>     if (result != null) {
>>>>         return result;
>>>>     }
>>>>     throw new CannotAdaptException(…);
>>>> }
>>>> }
>>>> 
>>> 
>>> Use is problematic because you would have to know whether you can call
>> the new method: So instead of an null check you now have an instanceof
>> check … Except for the Resource interface which would be extended to extend
>> from Adaptable2 as well.
>>> 
>>> (3) Document, that Adaptable.adaptTo may throw a RuntimeException.
>>> 
>>> The problem here is, that this may conceptually break existing callers
>> of Adaptable.adaptTo which don't expect an exception at all — presumably
>> this is a minor nuisance because technically a RuntimeException may always
>> be thrown.
>>> 
>>> Regards
>>> Felix
>> 
>> 
> 
> 
> -- 
> Carsten Ziegeler
> Adobe Research Switzerland
> cziege...@apache.org

Reply via email to