Merge remote-tracking branch 'origin/master' into okhttp-gson-next-gen-better-error

This commit is contained in:
William Cheng 2021-12-07 21:52:51 +08:00
commit 3539b39c73
19 changed files with 51 additions and 97 deletions

View File

@ -64,12 +64,14 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
}
{{/anyOf}}
throw new IOException("Failed to deserialize as the type doesn't match anyOf schemas: {{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}");
throw new IOException("Failed to serialize as the type doesn't match anyOf schemas: {{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}");
}
@Override
public {{classname}} read(JsonReader in) throws IOException {
Object deserialized = null;
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
{{#useOneOfDiscriminatorLookup}}
{{#discriminator}}
// use discriminator value for faster anyOf lookup
@ -78,7 +80,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
switch (discriminatorValue) {
{{#mappedModels}}
case "{{{mappingName}}}":
deserialized = gson.fromJson(in, {{{modelName}}}.class);
deserialized = adapter{{modelName}}.fromJsonTree(jsonObject);
new{{classname}}.setActualInstance(deserialized);
return new{{classname}};
{{/mappedModels}}
@ -92,7 +94,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
{{#anyOf}}
// deserialize {{{.}}}
try {
deserialized = gson.fromJson(in, {{.}}.class);
deserialized = adapter{{.}}.fromJsonTree(jsonObject);
log.log(Level.FINER, "Input data matches schema '{{{.}}}'");
{{classname}} ret = new {{classname}}();
ret.setActualInstance(deserialized);
@ -103,7 +105,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
}
{{/anyOf}}
throw new IOException("Failed deserialization for {{classname}}: no match found.");
throw new IOException(String.format("Failed deserialization for {{classname}} as data doesn't match anyOf schmeas: {{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}. JSON: %s", jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -64,7 +64,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
}
{{/oneOf}}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}");
}
@Override
@ -80,7 +80,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
switch (discriminatorValue) {
{{#mappedModels}}
case "{{{mappingName}}}":
deserialized = adapter{{.}}.fromJsonTree(jsonObject);
deserialized = adapter{{modelName}}.fromJsonTree(jsonObject);
new{{classname}}.setActualInstance(deserialized);
return new{{classname}};
{{/mappedModels}}
@ -110,7 +110,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
return ret;
}
throw new IOException(String.format("Failed deserialization for {{classname}}: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for {{classname}}: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -1888,11 +1888,6 @@ components:
type: string
pattern: /^[A-Z\s]*$/i
nullable: true
pineapple:
type: object
properties:
origin:
type: string
banana:
type: object
properties:
@ -1955,7 +1950,6 @@ components:
color:
type: string
anyOf:
- $ref: '#/components/schemas/pineapple'
- $ref: '#/components/schemas/apple'
- $ref: '#/components/schemas/banana'
additionalProperties: false

View File

@ -66,7 +66,6 @@ docs/ParentPet.md
docs/Pet.md
docs/PetApi.md
docs/Pig.md
docs/Pineapple.md
docs/Quadrilateral.md
docs/QuadrilateralInterface.md
docs/ReadOnlyFirst.md
@ -179,7 +178,6 @@ src/main/java/org/openapitools/client/model/OuterEnumIntegerDefaultValue.java
src/main/java/org/openapitools/client/model/ParentPet.java
src/main/java/org/openapitools/client/model/Pet.java
src/main/java/org/openapitools/client/model/Pig.java
src/main/java/org/openapitools/client/model/Pineapple.java
src/main/java/org/openapitools/client/model/Quadrilateral.java
src/main/java/org/openapitools/client/model/QuadrilateralInterface.java
src/main/java/org/openapitools/client/model/ReadOnlyFirst.java

View File

@ -213,7 +213,6 @@ Class | Method | HTTP request | Description
- [ParentPet](docs/ParentPet.md)
- [Pet](docs/Pet.md)
- [Pig](docs/Pig.md)
- [Pineapple](docs/Pineapple.md)
- [Quadrilateral](docs/Quadrilateral.md)
- [QuadrilateralInterface](docs/QuadrilateralInterface.md)
- [ReadOnlyFirst](docs/ReadOnlyFirst.md)

View File

@ -2053,11 +2053,6 @@ components:
pattern: /^[A-Z\s]*$/i
type: string
type: object
pineapple:
properties:
origin:
type: string
type: object
banana:
properties:
lengthCm:
@ -2118,7 +2113,6 @@ components:
gmFruit:
additionalProperties: false
anyOf:
- $ref: '#/components/schemas/pineapple'
- $ref: '#/components/schemas/apple'
- $ref: '#/components/schemas/banana'
properties:

View File

@ -8,8 +8,8 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**color** | **String** | | [optional]
**origin** | **String** | | [optional]
**cultivar** | **String** | | [optional]
**origin** | **String** | | [optional]
**lengthCm** | **BigDecimal** | | [optional]

View File

@ -270,7 +270,6 @@ public class JSON {
.registerTypeAdapterFactory(new org.openapitools.client.model.ParentPet.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(new org.openapitools.client.model.Pet.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(new org.openapitools.client.model.Pig.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(new org.openapitools.client.model.Pineapple.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(new org.openapitools.client.model.Quadrilateral.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(new org.openapitools.client.model.QuadrilateralInterface.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(new org.openapitools.client.model.ReadOnlyFirst.CustomTypeAdapterFactory())

View File

@ -97,7 +97,7 @@ public class Fruit extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: Apple, Banana");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: Apple, Banana");
}
@Override
@ -133,7 +133,7 @@ public class Fruit extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for Fruit: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for Fruit: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -97,7 +97,7 @@ public class FruitReq extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: AppleReq, BananaReq");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: AppleReq, BananaReq");
}
@Override
@ -133,7 +133,7 @@ public class FruitReq extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for FruitReq: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for FruitReq: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -26,7 +26,6 @@ import java.io.IOException;
import java.math.BigDecimal;
import org.openapitools.client.model.Apple;
import org.openapitools.client.model.Banana;
import org.openapitools.client.model.Pineapple;
import javax.ws.rs.core.GenericType;
@ -75,7 +74,6 @@ public class GmFruit extends AbstractOpenApiSchema {
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
final TypeAdapter<Apple> adapterApple = gson.getDelegateAdapter(this, TypeToken.get(Apple.class));
final TypeAdapter<Banana> adapterBanana = gson.getDelegateAdapter(this, TypeToken.get(Banana.class));
final TypeAdapter<Pineapple> adapterPineapple = gson.getDelegateAdapter(this, TypeToken.get(Pineapple.class));
return (TypeAdapter<T>) new TypeAdapter<GmFruit>() {
@Override
@ -99,23 +97,18 @@ public class GmFruit extends AbstractOpenApiSchema {
return;
}
// check if the actual instance is of the type `Pineapple`
if (value.getActualInstance() instanceof Pineapple) {
JsonObject obj = adapterPineapple.toJsonTree((Pineapple)value.getActualInstance()).getAsJsonObject();
elementAdapter.write(out, obj);
return;
}
throw new IOException("Failed to deserialize as the type doesn't match anyOf schemas: Apple, Banana, Pineapple");
throw new IOException("Failed to serialize as the type doesn't match anyOf schemas: Apple, Banana");
}
@Override
public GmFruit read(JsonReader in) throws IOException {
Object deserialized = null;
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
// deserialize Apple
try {
deserialized = gson.fromJson(in, Apple.class);
deserialized = adapterApple.fromJsonTree(jsonObject);
log.log(Level.FINER, "Input data matches schema 'Apple'");
GmFruit ret = new GmFruit();
ret.setActualInstance(deserialized);
@ -127,7 +120,7 @@ public class GmFruit extends AbstractOpenApiSchema {
// deserialize Banana
try {
deserialized = gson.fromJson(in, Banana.class);
deserialized = adapterBanana.fromJsonTree(jsonObject);
log.log(Level.FINER, "Input data matches schema 'Banana'");
GmFruit ret = new GmFruit();
ret.setActualInstance(deserialized);
@ -137,19 +130,7 @@ public class GmFruit extends AbstractOpenApiSchema {
log.log(Level.FINER, "Input data does not match schema 'Banana'", e);
}
// deserialize Pineapple
try {
deserialized = gson.fromJson(in, Pineapple.class);
log.log(Level.FINER, "Input data matches schema 'Pineapple'");
GmFruit ret = new GmFruit();
ret.setActualInstance(deserialized);
return ret;
} catch (Exception e) {
// deserialization failed, continue
log.log(Level.FINER, "Input data does not match schema 'Pineapple'", e);
}
throw new IOException("Failed deserialization for GmFruit: no match found.");
throw new IOException(String.format("Failed deserialization for GmFruit as data doesn't match anyOf schmeas: Apple, Banana. JSON: %s", jsonObject.toString()));
}
}.nullSafe();
}
@ -172,18 +153,11 @@ public class GmFruit extends AbstractOpenApiSchema {
setActualInstance(o);
}
public GmFruit(Pineapple o) {
super("anyOf", Boolean.FALSE);
setActualInstance(o);
}
static {
schemas.put("Apple", new GenericType<Apple>() {
});
schemas.put("Banana", new GenericType<Banana>() {
});
schemas.put("Pineapple", new GenericType<Pineapple>() {
});
}
@Override
@ -194,7 +168,7 @@ public class GmFruit extends AbstractOpenApiSchema {
/**
* Set the instance that matches the anyOf child schema, check
* the instance parameter is valid against the anyOf child schemas:
* Apple, Banana, Pineapple
* Apple, Banana
*
* It could be an instance of the 'anyOf' schemas.
* The anyOf child schemas may themselves be a composed schema (allOf, anyOf, anyOf).
@ -211,19 +185,14 @@ public class GmFruit extends AbstractOpenApiSchema {
return;
}
if (instance instanceof Pineapple) {
super.setActualInstance(instance);
return;
}
throw new RuntimeException("Invalid instance type. Must be Apple, Banana, Pineapple");
throw new RuntimeException("Invalid instance type. Must be Apple, Banana");
}
/**
* Get the actual instance, which can be the following:
* Apple, Banana, Pineapple
* Apple, Banana
*
* @return The actual instance (Apple, Banana, Pineapple)
* @return The actual instance (Apple, Banana)
*/
@Override
public Object getActualInstance() {
@ -252,16 +221,5 @@ public class GmFruit extends AbstractOpenApiSchema {
return (Banana)super.getActualInstance();
}
/**
* Get the actual instance of `Pineapple`. If the actual instance is not `Pineapple`,
* the ClassCastException will be thrown.
*
* @return The actual instance of `Pineapple`
* @throws ClassCastException if the instance is not `Pineapple`
*/
public Pineapple getPineapple() throws ClassCastException {
return (Pineapple)super.getActualInstance();
}
}

View File

@ -105,7 +105,7 @@ public class Mammal extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: Pig, Whale, Zebra");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: Pig, Whale, Zebra");
}
@Override
@ -151,7 +151,7 @@ public class Mammal extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for Mammal: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for Mammal: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -96,7 +96,7 @@ public class NullableShape extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: Quadrilateral, Triangle");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: Quadrilateral, Triangle");
}
@Override
@ -132,7 +132,7 @@ public class NullableShape extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for NullableShape: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for NullableShape: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -96,7 +96,7 @@ public class Pig extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: BasquePig, DanishPig");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: BasquePig, DanishPig");
}
@Override
@ -132,7 +132,7 @@ public class Pig extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for Pig: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for Pig: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -96,7 +96,7 @@ public class Quadrilateral extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: ComplexQuadrilateral, SimpleQuadrilateral");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: ComplexQuadrilateral, SimpleQuadrilateral");
}
@Override
@ -132,7 +132,7 @@ public class Quadrilateral extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for Quadrilateral: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for Quadrilateral: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -96,7 +96,7 @@ public class Shape extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: Quadrilateral, Triangle");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: Quadrilateral, Triangle");
}
@Override
@ -132,7 +132,7 @@ public class Shape extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for Shape: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for Shape: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -96,7 +96,7 @@ public class ShapeOrNull extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: Quadrilateral, Triangle");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: Quadrilateral, Triangle");
}
@Override
@ -132,7 +132,7 @@ public class ShapeOrNull extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for ShapeOrNull: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for ShapeOrNull: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -105,7 +105,7 @@ public class Triangle extends AbstractOpenApiSchema {
return;
}
throw new IOException("Failed to deserialize as the type doesn't match oneOf schemas: EquilateralTriangle, IsoscelesTriangle, ScaleneTriangle");
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: EquilateralTriangle, IsoscelesTriangle, ScaleneTriangle");
}
@Override
@ -151,7 +151,7 @@ public class Triangle extends AbstractOpenApiSchema {
return ret;
}
throw new IOException(String.format("Failed deserialization for Triangle: %d classes match result, expected 1", match));
throw new IOException(String.format("Failed deserialization for Triangle: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
}
}.nullSafe();
}

View File

@ -294,7 +294,6 @@ public class JSONTest {
public void testAnyOfSchemaWithoutDiscriminator() throws Exception {
{
String str = "{ \"cultivar\": \"golden delicious\", \"origin\": \"japan\" }";
String str2 = "{ \"origin_typo\": \"japan\" }";
// make sure deserialization works for pojo object
Apple a = json.getGson().fromJson(str, Apple.class);
@ -309,8 +308,19 @@ public class JSONTest {
assertEquals(json.getGson().toJson(inst), "{\"cultivar\":\"golden delicious\",\"origin\":\"japan\"}");
assertEquals(json.getGson().toJson(o), "{\"cultivar\":\"golden delicious\",\"origin\":\"japan\"}");
String str2 = "{ \"origin_typo\": \"japan\" }";
// no match
Exception exception = assertThrows(com.google.gson.JsonSyntaxException.class, () -> {
Exception exception = assertThrows(java.lang.IllegalArgumentException.class, () -> {
Apple o3 = json.getGson().fromJson(str2, Apple.class);
});
// no match
Exception exception3 = assertThrows(java.lang.IllegalArgumentException.class, () -> {
Banana o2 = json.getGson().fromJson(str2, Banana.class);
});
// no match
Exception exception4 = assertThrows(com.google.gson.JsonSyntaxException.class, () -> {
GmFruit o2 = json.getGson().fromJson(str2, GmFruit.class);
});
}
@ -359,7 +369,7 @@ public class JSONTest {
Exception exception = assertThrows(com.google.gson.JsonSyntaxException.class, () -> {
FruitReq o = json.getGson().fromJson(str, FruitReq.class);
});
assertTrue(exception.getMessage().contains("Failed deserialization for FruitReq: 0 classes match result"));
assertTrue(exception.getMessage().contains("Failed deserialization for FruitReq: 0 classes match result, expected 1. JSON: {\"cultivar\":\"golden delicious\",\"mealy\":false,\"garbage_prop\":\"abc\"}"));
}
{
String str = "{ \"lengthCm\": 17 }";