Improve OutOfScopeException so that it tells you which key it was trying to
get.
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=62699406
diff --git a/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java b/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
index a439dba..5249fac 100644
--- a/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
+++ b/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
@@ -19,7 +19,9 @@
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.inject.Inject;
+import com.google.inject.Key;
import com.google.inject.OutOfScopeException;
+import com.google.inject.internal.Errors;
import java.io.IOException;
import java.lang.ref.WeakReference;
@@ -142,27 +144,27 @@
}
}
- static HttpServletRequest getOriginalRequest() {
- return getContext().getOriginalRequest();
+ static HttpServletRequest getOriginalRequest(Key<?> key) {
+ return getContext(key).getOriginalRequest();
}
- static HttpServletRequest getRequest() {
- return getContext().getRequest();
+ static HttpServletRequest getRequest(Key<?> key) {
+ return getContext(key).getRequest();
}
- static HttpServletResponse getResponse() {
- return getContext().getResponse();
+ static HttpServletResponse getResponse(Key<?> key) {
+ return getContext(key).getResponse();
}
static ServletContext getServletContext() {
return servletContext.get();
}
- private static Context getContext() {
+ private static Context getContext(Key<?> key) {
Context context = localContext.get();
if (context == null) {
- throw new OutOfScopeException("Cannot access scoped object. Either we"
- + " are not currently inside an HTTP Servlet request, or you may"
+ throw new OutOfScopeException("Cannot access scoped [" + Errors.convert(key)
+ + "]. Either we are not currently inside an HTTP Servlet request, or you may"
+ " have forgotten to apply " + GuiceFilter.class.getName()
+ " as a servlet filter for this request.");
}
diff --git a/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java b/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
index 8043ca9..046b8b6 100644
--- a/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
+++ b/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
@@ -20,6 +20,7 @@
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
+import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Provides;
import com.google.inject.Singleton;
@@ -102,15 +103,15 @@
}
@Provides @RequestScoped HttpServletRequest provideHttpServletRequest() {
- return GuiceFilter.getRequest();
+ return GuiceFilter.getRequest(Key.get(HttpServletRequest.class));
}
@Provides @RequestScoped HttpServletResponse provideHttpServletResponse() {
- return GuiceFilter.getResponse();
+ return GuiceFilter.getResponse(Key.get(HttpServletResponse.class));
}
@Provides HttpSession provideHttpSession() {
- return GuiceFilter.getRequest().getSession();
+ return GuiceFilter.getRequest(Key.get(HttpSession.class)).getSession();
}
@SuppressWarnings("unchecked") // defined by getParameterMap()
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java b/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
index cd593bf..9d4e278 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
@@ -103,7 +103,7 @@
// {@code GuiceFilter.getRequest()}.
//
// This _correctly_ throws up if the thread is out of scope.
- HttpServletRequest request = GuiceFilter.getOriginalRequest();
+ HttpServletRequest request = GuiceFilter.getOriginalRequest(key);
if (REQUEST_CONTEXT_KEYS.contains(key)) {
// Don't store these keys as attributes, since they are handled by
// GuiceFilter itself.
@@ -144,11 +144,11 @@
* HTTP session scope.
*/
public static final Scope SESSION = new Scope() {
- public <T> Provider<T> scope(Key<T> key, final Provider<T> creator) {
+ public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
final String name = key.toString();
return new Provider<T>() {
public T get() {
- HttpSession session = GuiceFilter.getRequest().getSession();
+ HttpSession session = GuiceFilter.getRequest(key).getSession();
synchronized (session) {
Object obj = session.getAttribute(name);
if (NullObject.INSTANCE == obj) {
@@ -217,7 +217,8 @@
// Snapshot the seed map and add all the instances to our continuing HTTP request.
final ContinuingHttpServletRequest continuingRequest =
- new ContinuingHttpServletRequest(GuiceFilter.getRequest());
+ new ContinuingHttpServletRequest(
+ GuiceFilter.getRequest(Key.get(HttpServletRequest.class)));
for (Map.Entry<Key<?>, Object> entry : seedMap.entrySet()) {
Object value = validateAndCanonicalizeValue(entry.getKey(), entry.getValue());
continuingRequest.setAttribute(entry.getKey().toString(), value);
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
index ae1750b..beb0873 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
@@ -16,6 +16,7 @@
package com.google.inject.servlet;
+import static com.google.inject.Asserts.assertContains;
import static com.google.inject.Asserts.reserialize;
import static com.google.inject.servlet.ServletTestUtils.newFakeHttpServletRequest;
import static com.google.inject.servlet.ServletTestUtils.newFakeHttpServletResponse;
@@ -35,6 +36,11 @@
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
+import com.google.inject.Provides;
+import com.google.inject.ProvisionException;
+import com.google.inject.internal.Errors;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
import com.google.inject.servlet.ServletScopes.NullObject;
import com.google.inject.util.Providers;
@@ -68,7 +74,6 @@
private static final Key<Map<String, String[]>> REQ_PARAMS_KEY
= new Key<Map<String, String[]>>(RequestParameters.class) {};
- private static final Key<InRequest> IN_REQUEST_KEY = Key.get(InRequest.class);
private static final Key<InRequest> IN_REQUEST_NULL_KEY = Key.get(InRequest.class, Null.class);
private static final Key<InSession> IN_SESSION_KEY = Key.get(InSession.class);
private static final Key<InSession> IN_SESSION_NULL_KEY = Key.get(InSession.class, Null.class);
@@ -78,6 +83,39 @@
//we need to clear the reference to the pipeline every test =(
GuiceFilter.reset();
}
+
+ public void testScopeExceptions() throws Exception {
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override protected void configure() {
+ install(new ServletModule());
+ }
+ @Provides @RequestScoped String provideString() { return "foo"; }
+ @Provides @SessionScoped Integer provideInteger() { return 1; }
+ @Provides @RequestScoped @Named("foo") String provideNamedString() { return "foo"; }
+ });
+
+ try {
+ injector.getInstance(String.class);
+ fail();
+ } catch(ProvisionException oose) {
+ assertContains(oose.getMessage(), "Cannot access scoped [java.lang.String].");
+ }
+
+ try {
+ injector.getInstance(Integer.class);
+ fail();
+ } catch(ProvisionException oose) {
+ assertContains(oose.getMessage(), "Cannot access scoped [java.lang.Integer].");
+ }
+
+ Key<?> key = Key.get(String.class, Names.named("foo"));
+ try {
+ injector.getInstance(key);
+ fail();
+ } catch(ProvisionException oose) {
+ assertContains(oose.getMessage(), "Cannot access scoped [" + Errors.convert(key) + "]");
+ }
+ }
public void testRequestAndResponseBindings() throws Exception {
final Injector injector = createInjector();
@@ -183,7 +221,7 @@
public void testRequestAndResponseBindings_matchesPassedParameters() throws Exception {
final int[] filterInvoked = new int[1];
final boolean[] servletInvoked = new boolean[1];
- final Injector injector = createInjector(new ServletModule() {
+ createInjector(new ServletModule() {
@Override protected void configureServlets() {
final HttpServletRequest[] previousReq = new HttpServletRequest[1];
final HttpServletResponse[] previousResp = new HttpServletResponse[1];
@@ -340,8 +378,7 @@
assertTrue(invoked[0]);
}
- public void testHttpSessionIsSerializable()
- throws IOException, ClassNotFoundException, ServletException {
+ public void testHttpSessionIsSerializable() throws Exception {
final Injector injector = createInjector();
final HttpServletRequest request = newFakeHttpServletRequest();
final HttpSession session = request.getSession();