Skip to content

Commit c1e1ae4

Browse files
authored
Merge pull request #110 from maxmind/sromani/better-reflection-exception
Add exception for argument mismatch in contructor
2 parents 7924fb6 + 4e9da0f commit c1e1ae4

File tree

4 files changed

+77
-6
lines changed

4 files changed

+77
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
CHANGELOG
22
=========
3-
43
2.1.0
54
------------------
65

7-
* Messages for `DeserializationException` have been improved and the
8-
cause is included, if any.
6+
* Messages for `DeserializationException` have been improved and the cause
7+
is included, if any. Moreover, the message provides detail about the involved
8+
types, if the exeption is caused by an `IllegalArgumentException`.
99

1010
2.0.0 (2020-10-13)
1111
------------------

src/main/java/com/maxmind/db/Decoder.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,17 @@ private <T> Object decodeMapIntoObject(int size, Class<T> cls)
439439
InvocationTargetException e) {
440440
throw new DeserializationException("Error creating object: " + e.getMessage(), e);
441441
}
442+
catch (IllegalArgumentException e){
443+
StringBuilder sbErrors = new StringBuilder();
444+
for (String key : parameterIndexes.keySet()) {
445+
int index = parameterIndexes.get(key);
446+
if (!parameters[index].getClass().isAssignableFrom( parameterTypes[index])) {
447+
sbErrors.append(" argument type mismatch in " + key + " MMDB Type: " + parameters[index].getClass().getCanonicalName()
448+
+ " Java Type: " +parameterTypes[index].getCanonicalName());
449+
}
450+
}
451+
throw new DeserializationException("Error creating object of type: " + cls.getSimpleName() + " - " + sbErrors.toString(), e);
452+
}
442453
}
443454

444455
private static <T> Constructor<T> findConstructor(Class<T> cls)

src/main/java/com/maxmind/db/Reader.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.net.InetAddress;
99
import java.nio.ByteBuffer;
1010
import java.util.concurrent.atomic.AtomicReference;
11+
import java.util.Optional;
1112
import java.util.concurrent.ConcurrentHashMap;
1213

1314
/**
@@ -177,9 +178,13 @@ record = this.readNode(buffer, record, bit);
177178
T dataRecord = null;
178179
if (record > nodeCount) {
179180
// record is a data pointer
180-
dataRecord = this.resolveDataPointer(buffer, record, cls);
181+
try {
182+
dataRecord = this.resolveDataPointer(buffer, record, cls);
183+
} catch (DeserializationException exception) {
184+
String msgCause = Optional.ofNullable(exception).map(Exception::getMessage).orElse("");
185+
throw new DeserializationException("Error getting record for IP " + ipAddress.toString() + " - " + msgCause, exception);
186+
}
181187
}
182-
183188
return new DatabaseRecord<>(dataRecord, ipAddress, pl);
184189
}
185190

src/test/java/com/maxmind/db/ReaderTest.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,61 @@ public TestModelSubdivision(
567567
}
568568
}
569569

570+
@Test
571+
public void testDecodeWrongTypeWithConstructorException() throws IOException {
572+
this.testReader = new Reader(getFile("GeoIP2-City-Test.mmdb"));
573+
DeserializationException ex = assertThrows(DeserializationException.class,
574+
() -> this.testReader.get( InetAddress.getByName("2.125.160.216"),
575+
TestModelSubdivisionsWithUnknownException.class));
576+
577+
assertThat(ex.getMessage(), containsString("Error getting record for IP /2.125.160.216 - Error creating object"));
578+
}
579+
580+
static class TestModelSubdivisionsWithUnknownException {
581+
List<TestModelSubdivision> subdivisions;
582+
583+
@MaxMindDbConstructor
584+
public TestModelSubdivisionsWithUnknownException (
585+
@MaxMindDbParameter(name="subdivisions")
586+
List<TestModelSubdivision> subdivisions
587+
) throws Exception{
588+
throw new Exception();
589+
}
590+
}
591+
592+
@Test
593+
public void testDecodeWrongTypeWithWrongArguments() throws IOException {
594+
this.testReader = new Reader(getFile("GeoIP2-City-Test.mmdb"));
595+
DeserializationException ex = assertThrows(DeserializationException.class,
596+
() -> this.testReader.get( InetAddress.getByName("2.125.160.216"),
597+
TestWrongModelSubdivisions.class));
598+
assertThat(ex.getMessage(), containsString("Error getting record for IP"));
599+
}
600+
601+
static class TestWrongModelSubdivisions {
602+
List<TestWrongModelSubdivision> subdivisions;
603+
604+
@MaxMindDbConstructor
605+
public TestWrongModelSubdivisions (
606+
@MaxMindDbParameter(name="subdivisions")
607+
List<TestWrongModelSubdivision> subdivisions
608+
) {
609+
this.subdivisions = subdivisions;
610+
}
611+
}
612+
613+
static class TestWrongModelSubdivision {
614+
Integer uint16Field;
615+
@MaxMindDbConstructor
616+
public TestWrongModelSubdivision(
617+
@MaxMindDbParameter(name="iso_code")
618+
Integer uint16Field
619+
) {
620+
this.uint16Field = uint16Field;
621+
;
622+
}
623+
}
624+
570625
@Test
571626
public void testDecodeConcurrentHashMap() throws IOException {
572627
this.testReader = new Reader(getFile("GeoIP2-City-Test.mmdb"));
@@ -775,7 +830,7 @@ public void voidTestMapKeyIsString() throws IOException {
775830
TestModelInvalidMap.class
776831
)
777832
);
778-
assertEquals("Map keys must be strings.", ex.getMessage());
833+
assertEquals("Error getting record for IP /2.125.160.216 - Map keys must be strings.", ex.getMessage());
779834
}
780835

781836
static class TestModelInvalidMap {

0 commit comments

Comments
 (0)