Skip to content

Commit

Permalink
Fix #3133: Add a better error message when custom map key is not on c…
Browse files Browse the repository at this point in the history
…lasspath.

See #3133 (comment)

Fixes #3133

RELNOTES=Fixes #3133: Adds a better error message when custom map key is not on classpath.
PiperOrigin-RevId: 418867510
  • Loading branch information
bcorso authored and Dagger Team committed Dec 30, 2021
1 parent 2a8c6b6 commit e4076b0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
19 changes: 18 additions & 1 deletion java/dagger/internal/codegen/binding/KeyFactory.java
Expand Up @@ -20,6 +20,7 @@
import static androidx.room.compiler.processing.compat.XConverters.toXProcessing;
import static com.google.auto.common.MoreTypes.isType;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.getOnlyElement;
import static dagger.internal.codegen.base.ProducerAnnotations.productionImplementationQualifier;
import static dagger.internal.codegen.base.ProducerAnnotations.productionQualifier;
Expand Down Expand Up @@ -253,7 +254,23 @@ private TypeMirror bindingMethodKeyType(
case SET:
return setOf(returnType);
case MAP:
TypeMirror mapKeyType = mapKeyType(toXProcessing(getMapKey(method).get(), processingEnv));
Optional<AnnotationMirror> mapKey = getMapKey(method);
// TODO(bcorso): We've added a special checkState here since a number of people have run
// into this particular case, but technically it shouldn't be necessary if we are properly
// doing superficial validation and deferring on unresolvable types. We should revisit
// whether this is necessary once we're able to properly defer this case.
checkState(
mapKey.isPresent(),
"Missing map key annotation for method: %s#%s. That method was annotated with: %s. If a"
+ " map key annotation is included in that list, it means Dagger wasn't able to"
+ " detect that it was a map key because the dependency is missing from the"
+ " classpath of the current build. To fix, add a dependency for the map key to the"
+ " current build. For more details, see"
+ " https://github.com/google/dagger/issues/3133#issuecomment-1002790894.",
method.getEnclosingElement(),
method,
method.getAnnotationMirrors());
TypeMirror mapKeyType = mapKeyType(toXProcessing(mapKey.get(), processingEnv));
return frameworkClassName.isPresent()
? mapOfFrameworkType(mapKeyType, frameworkClassName.get(), returnType)
: mapOf(mapKeyType, returnType);
Expand Down
Expand Up @@ -37,12 +37,14 @@ public class TransitiveMapKeyTest {
@Test
public void testTransitiveMapKey_WithImplementation() throws IOException {
BuildResult result = setupRunnerWith("implementation").buildAndFail();

// TODO(bcorso): This is a repro of https://github.com/google/dagger/issues/3133.
// We should update the error message to include the provision method.
assertThat(result.getOutput()).contains("Task :app:compileJava FAILED");
assertThat(result.getOutput())
.contains("Caused by: java.util.NoSuchElementException: No value present");
.contains(
"Missing map key annotation for method: library1.MyModule#provideString(). "
+ "That method was annotated with: "
+ "@dagger.Provides,"
+ "@dagger.multibindings.IntoMap,"
+ "@library2.MyMapKey(\"some-key\")");
}

@Test
Expand Down

0 comments on commit e4076b0

Please sign in to comment.