Yup, for our internals we actually have a two-pronged approach where we try
to eagerly validate whatever we can (using getAllBindings) at startup, and
then continue to monitor for any stragglers using a ProvisionListener.

sam

On Wed, Nov 25, 2015, 8:38 PM Tavian Barnes <[email protected]> wrote:

> Ah, that's another approach to http://stackoverflow.com/q/18474368/502399
> :)
>
> On Wednesday, 25 November 2015 17:54:13 UTC-5, Sam Berlin wrote:
>
>> You can write your own analysis using the SPI and fail eagerly.  This
>> will work only if users don't inject the Injector.  We do this internally
>> for singletons to ensure that only other singletons or unscoped things (or
>> Providers) are injected into singletons. The APIs involved would be
>> Binding.acceptTargetVisitor(BindingTargetVisitor), checking dependencies
>> (often by casting to HasDependencies, for linked bindings getting the link,
>> potentially implementing extension-specific BindingTargetVisitor
>> subinterfaces), and keeping track of the path as you're recursing through
>> dependencies.  The starting point for visiting would be each binding in
>> injector.getAllBindings().values().  (And you could keep track of what
>> you've visited to short-circuit on later visits, to avoid redoing the same
>> work.)
>>
>> sam
>>
>>
>>
>> On Wed, Nov 25, 2015 at 5:42 PM Tavian Barnes <[email protected]> wrote:
>>
> All the semantic information you want is thrown away very early by Guice,
>>> so there's probably not a way to get the kind of details that you want.
>>> The internal implementation
>>> <https://github.com/google/guice/blob/master/core/src/com/google/inject/internal/Errors.java>
>>>  uses
>>> the same Message class that you see in the ProvisionException.
>>>
>>>
>>> On Wednesday, 25 November 2015 03:46:36 UTC-5, jwa wrote:
>>>>
>>>> I would like to intercept some of the exceptions being thrown by Guice,
>>>> with access to the full context of the underlying error, and use
>>>> domain-specific details to come up with meaningful error messages.
>>>>
>>>> To illustrate this problem I am using a vastly simplified domain, this
>>>> may be a bit tenuous, bear with me.
>>>>
>>>> I provide my clients with a simplified API which allows them to
>>>> build-up the event without exposing them to the fact that Guice will be
>>>> used to wire everything together:
>>>>
>>>> AthelticsBuilder builder = new AthelticsBuilder()
>>>>   .withTicketIssuer(ResultRecorded.class)  // <-- This is a singleton,
>>>> one ticket issuer per event
>>>>   .withObserver(ResultRecorded.class)      // <--- This is
>>>> race-scoped, one created per race
>>>>   .addRace("100 meter sprint")
>>>>   .build();
>>>>
>>>> Behind the scenes the AthleticsBuilder will use Guice to obtain
>>>> instances of each of the classes described above. Framework-related
>>>> dependencies may be injected into these classes, for example RaceObservers
>>>> might want to gain access to the StopWatch that is timing the event they
>>>> are responsible for observing:
>>>>
>>>> public class ResultRecorder implements RaceObserver {
>>>>   @Inject
>>>>   public ResultRecorder(Race race, StopWatch watch) { /* ... */ }
>>>> }
>>>>
>>>> The injection of these race-specific dependencies is facilitated by a
>>>> custom "RaceScope" which is entered/exited as the AthelticsBuilder creates
>>>> each race added to the builder.
>>>>
>>>> It is possible for my API clients to make rather silly mistakes. For
>>>> example, they might ask for a StopWatch to be injected into their
>>>> TicketIssuer. This is not legal, as the TicketIssuer is a singleton, and
>>>> has no access to members injected by the RaceScope. For eaxmple, if the
>>>> following constructor is used:
>>>>
>>>> public class TicketMachine implements TicketIssuer {
>>>>
>>>>   @Inject
>>>>   public TicketMachine(StopWatch watch) { /* ... */ }
>>>> }
>>>>
>>>> Guice will throw a ProvisionException when attempting to instantiate
>>>> the TicketMachine. This will have the following error:
>>>>
>>>> Caused by: com.google.inject.ProvisionException: Unable to provision,
>>>> see the following errors:
>>>>
>>>> 1) Error in custom provider, com.google.inject.OutOfScopeException:
>>>> Cannot access Key[type=com.acme.StopWatch, annotation=[none]] outside of a
>>>> scoping block
>>>>   at com.acme.RaceScopeModule.configure(RaceScopeModule.java:25)
>>>>   while locating com.acme.StopWatch
>>>>     for parameter 0 at
>>>> com.acme.TicketMachine.<init>(TicketMachine.java:85)
>>>>   while locating com.acme.TicketMachine
>>>>
>>>> This is rather unfortunate for two reasons:
>>>>
>>>>    - It exposes my API clients to the fact I'm using Guice. My API
>>>>    completely insulates them from this, which is nice. It's only when 
>>>> errors
>>>>    are encountered that they suddenly become aware what's happening
>>>>    under-the-covers
>>>>    - The API consumer isn't likely to be able to decipher this error,
>>>>    and identifying the underlying issue
>>>>
>>>> It would be much nicer if I could intercept this exception (more likely
>>>> the underlying exception) and provide something far more meaningful: 
>>>> "*TicketMachine
>>>> cannot access com.acme.StopWatch as it does not have reference to a race*
>>>> ".
>>>>
>>>> To be able to achieve this, I'd need to be able to intercept the exact
>>>> details of the binding error. Simply catching ProvisionException is of
>>>> little use to me; it just contains "Messages", which don't have any of the
>>>> rich context-specific information I need to produce more meaningful errors.
>>>>
>>>> Is there some mechanism for handling / intercepting this errors, in
>>>> order to produce more meaningful exceptions?
>>>>
>>>> Any pointers would be greatly appreciated.
>>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "google-guice" group.
>>>
>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to [email protected].
>>> To post to this group, send email to [email protected].
>>
>>
>>> Visit this group at http://groups.google.com/group/google-guice.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/google-guice/9a4d8bd2-114c-4795-b8ca-90902ab9b984%40googlegroups.com
>>> <https://groups.google.com/d/msgid/google-guice/9a4d8bd2-114c-4795-b8ca-90902ab9b984%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "google-guice" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/google-guice.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/google-guice/d748c616-0001-4201-a170-a914b6f3bdab%40googlegroups.com
> <https://groups.google.com/d/msgid/google-guice/d748c616-0001-4201-a170-a914b6f3bdab%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-guice/CAJEBNUe1c2U8Ebc133wTf0TMPjBcNPKhi8RX7La1-GVbCybxog%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to