My favorites | Sign in
Google
                
Search
for
Updated Dec 05, 2008 by limpbizkit
ThrowingProviders  
throwing providers extension tutorial

Throwing Providers

Guice isn't very good at handling exceptions that occur during provision.

ThrowingProviders are an alternative to Providers that allow a checked exception to be thrown.

The ThrowingProvider interface is similar to Provider, but with a generic Exception type:

public interface ThrowingProvider<T,E extends Exception> {
  T get() throws E;
}

For each application exception, create an interface that extends the ThrowingProvider. For our news widget application, we created the FeedProvider interface that throws a FeedUnavailableException:

public interface FeedProvider<T> extends ThrowingProvider<T, FeedUnavailableException> { }

After implementing our WordlNewsFeedProvider and SportsFeedProvider, we bind them in our module using ThrowingProviderBinder:

public static class FeedModule extends AbstractModule {
  protected void configure() {
    ThrowingProviderBinder.create(binder())
        .bind(FeedProvider.class, BbcFeed.class)
        .annotatedWith(WorldNews.class)
        .to(WorldNewsFeedProvider.class)
        .in(HourlyScoped.class);

    ThrowingProviderBinder.create(binder())
        .bind(FeedProvider.class, BbcFeed.class)
        .annotatedWith(Sports.class)
        .to(SportsFeedProvider.class)
        .in(QuarterHourlyScoped.class);
  }
}

Finally, we can inject the FeedProviders throughout our application code. Whenever we call get(), the compiler reminds us to handle the FeedUnavailableException:

public class BbcNewsWidget {
  private final FeedProvider<BbcFeed> worldNewsFeedProvider;
  private final FeedProvider<BbcFeed> sportsFeedProvider;

  @Inject
  public BbcNewsWidget(
      @WorldNews FeedProvider<BbcFeed> worldNewsFeedProvider,
      @Sports FeedProvider<BbcFeed> sportsFeedProvider) {
    this.worldNewsFeedProvider = worldNewsFeedProvider;
    this.sportsFeedProvider = sportsFeedProvider;
  }

  public GxpClosure render() {
    try {
      BbcFeed bbcWorldNews = worldNewsFeedProvider.get();
      BbcFeed bbcSports = sportsFeedProvider.get();
      return NewsWidgetBody.getGxpClosure(bbcWorldNews, bbcSports);
    } catch (FeedUnavailableException e) {
      return UnavailableWidgetBody.getGxpClosure();
    }
  }
}

Notes on Scoping

Scopes work the same way they do with Providers. Each time get() is called, the returned object will be scoped appropriately. Exceptions are also scoped. For example, when worldNewsFeedProvider.get() throws an exception, the same exception instance will be thrown for all callers within the scope.


Sign in to add a comment