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 <taviana...@gmail.com> 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 google-guice+unsubscr...@googlegroups.com.
> To post to this group, send email to google-guice@googlegroups.com.
> 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 google-guice+unsubscr...@googlegroups.com.
To post to this group, send email to google-guice@googlegroups.com.
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/CAJEBNUcwoyY4mgW03Na1c1mVYZQ4Q_hY4io2tLdpOWKqGh7paQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to