Skip to content

Commit

Permalink
better error messages for oneOf in java okhttp-gson (OpenAPITools#12311)
Browse files Browse the repository at this point in the history
  • Loading branch information
wing328 authored May 10, 2022
1 parent ad3b5f7 commit 68360ca
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
{{/discriminator}}
{{/useOneOfDiscriminatorLookup}}
int match = 0;
ArrayList<String> errorMessages = new ArrayList<>();
TypeAdapter actualAdapter = elementAdapter;

{{#oneOf}}
Expand All @@ -107,6 +108,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
log.log(Level.FINER, "Input data matches schema '{{{.}}}'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for {{{.}}} failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema '{{{.}}}'", e);
}

Expand All @@ -117,7 +119,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. JSON: %s", match, jsonObject.toString()));
throw new IOException(String.format("Failed deserialization for {{classname}}: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonObject.toString()));
}
}.nullSafe();
}
Expand Down Expand Up @@ -210,17 +212,19 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
public static void validateJsonObject(JsonObject jsonObj) throws IOException {
// validate oneOf schemas one by one
int validCount = 0;
ArrayList<String> errorMessages = new ArrayList<>();
{{#oneOf}}
// validate the json string with {{{.}}}
try {
{{{.}}}.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for {{{.}}} failed with `%s`.", e.getMessage()));
// continue to the next one
}
{{/oneOf}}
if (validCount != 1) {
throw new IOException(String.format("The JSON string is invalid for {{classname}} with oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}. %d class(es) match the result, expected 1. JSON: %s", validCount, jsonObj.toString()));
throw new IOException(String.format("The JSON string is invalid for {{classname}} with oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonObj.toString()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public Fruit read(JsonReader in) throws IOException {
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();

int match = 0;
ArrayList<String> errorMessages = new ArrayList<>();
TypeAdapter actualAdapter = elementAdapter;

// deserialize Apple
Expand All @@ -117,6 +118,7 @@ public Fruit read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'Apple'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for Apple failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'Apple'", e);
}

Expand All @@ -129,6 +131,7 @@ public Fruit read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'Banana'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for Banana failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'Banana'", e);
}

Expand All @@ -138,7 +141,7 @@ public Fruit read(JsonReader in) throws IOException {
return ret;
}

throw new IOException(String.format("Failed deserialization for Fruit: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
throw new IOException(String.format("Failed deserialization for Fruit: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonObject.toString()));
}
}.nullSafe();
}
Expand Down Expand Up @@ -239,22 +242,25 @@ public Banana getBanana() throws ClassCastException {
public static void validateJsonObject(JsonObject jsonObj) throws IOException {
// validate oneOf schemas one by one
int validCount = 0;
ArrayList<String> errorMessages = new ArrayList<>();
// validate the json string with Apple
try {
Apple.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for Apple failed with `%s`.", e.getMessage()));
// continue to the next one
}
// validate the json string with Banana
try {
Banana.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for Banana failed with `%s`.", e.getMessage()));
// continue to the next one
}
if (validCount != 1) {
throw new IOException(String.format("The JSON string is invalid for Fruit with oneOf schemas: Apple, Banana. %d class(es) match the result, expected 1. JSON: %s", validCount, jsonObj.toString()));
throw new IOException(String.format("The JSON string is invalid for Fruit with oneOf schemas: Apple, Banana. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonObj.toString()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public FruitReq read(JsonReader in) throws IOException {
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();

int match = 0;
ArrayList<String> errorMessages = new ArrayList<>();
TypeAdapter actualAdapter = elementAdapter;

// deserialize AppleReq
Expand All @@ -117,6 +118,7 @@ public FruitReq read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'AppleReq'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for AppleReq failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'AppleReq'", e);
}

Expand All @@ -129,6 +131,7 @@ public FruitReq read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'BananaReq'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for BananaReq failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'BananaReq'", e);
}

Expand All @@ -138,7 +141,7 @@ public FruitReq read(JsonReader in) throws IOException {
return ret;
}

throw new IOException(String.format("Failed deserialization for FruitReq: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
throw new IOException(String.format("Failed deserialization for FruitReq: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonObject.toString()));
}
}.nullSafe();
}
Expand Down Expand Up @@ -244,22 +247,25 @@ public BananaReq getBananaReq() throws ClassCastException {
public static void validateJsonObject(JsonObject jsonObj) throws IOException {
// validate oneOf schemas one by one
int validCount = 0;
ArrayList<String> errorMessages = new ArrayList<>();
// validate the json string with AppleReq
try {
AppleReq.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for AppleReq failed with `%s`.", e.getMessage()));
// continue to the next one
}
// validate the json string with BananaReq
try {
BananaReq.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for BananaReq failed with `%s`.", e.getMessage()));
// continue to the next one
}
if (validCount != 1) {
throw new IOException(String.format("The JSON string is invalid for FruitReq with oneOf schemas: AppleReq, BananaReq. %d class(es) match the result, expected 1. JSON: %s", validCount, jsonObj.toString()));
throw new IOException(String.format("The JSON string is invalid for FruitReq with oneOf schemas: AppleReq, BananaReq. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonObj.toString()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ public Mammal read(JsonReader in) throws IOException {
}

int match = 0;
ArrayList<String> errorMessages = new ArrayList<>();
TypeAdapter actualAdapter = elementAdapter;

// deserialize Pig
Expand All @@ -149,6 +150,7 @@ public Mammal read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'Pig'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for Pig failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'Pig'", e);
}

Expand All @@ -161,6 +163,7 @@ public Mammal read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'Whale'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for Whale failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'Whale'", e);
}

Expand All @@ -173,6 +176,7 @@ public Mammal read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'Zebra'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for Zebra failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'Zebra'", e);
}

Expand All @@ -182,7 +186,7 @@ public Mammal read(JsonReader in) throws IOException {
return ret;
}

throw new IOException(String.format("Failed deserialization for Mammal: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
throw new IOException(String.format("Failed deserialization for Mammal: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonObject.toString()));
}
}.nullSafe();
}
Expand Down Expand Up @@ -306,29 +310,33 @@ public Zebra getZebra() throws ClassCastException {
public static void validateJsonObject(JsonObject jsonObj) throws IOException {
// validate oneOf schemas one by one
int validCount = 0;
ArrayList<String> errorMessages = new ArrayList<>();
// validate the json string with Pig
try {
Pig.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for Pig failed with `%s`.", e.getMessage()));
// continue to the next one
}
// validate the json string with Whale
try {
Whale.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for Whale failed with `%s`.", e.getMessage()));
// continue to the next one
}
// validate the json string with Zebra
try {
Zebra.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for Zebra failed with `%s`.", e.getMessage()));
// continue to the next one
}
if (validCount != 1) {
throw new IOException(String.format("The JSON string is invalid for Mammal with oneOf schemas: Pig, Whale, Zebra. %d class(es) match the result, expected 1. JSON: %s", validCount, jsonObj.toString()));
throw new IOException(String.format("The JSON string is invalid for Mammal with oneOf schemas: Pig, Whale, Zebra. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonObj.toString()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public NullableShape read(JsonReader in) throws IOException {
}

int match = 0;
ArrayList<String> errorMessages = new ArrayList<>();
TypeAdapter actualAdapter = elementAdapter;

// deserialize Quadrilateral
Expand All @@ -136,6 +137,7 @@ public NullableShape read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'Quadrilateral'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for Quadrilateral failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'Quadrilateral'", e);
}

Expand All @@ -148,6 +150,7 @@ public NullableShape read(JsonReader in) throws IOException {
log.log(Level.FINER, "Input data matches schema 'Triangle'");
} catch (Exception e) {
// deserialization failed, continue
errorMessages.add(String.format("Deserialization for Triangle failed with `%s`.", e.getMessage()));
log.log(Level.FINER, "Input data does not match schema 'Triangle'", e);
}

Expand All @@ -157,7 +160,7 @@ public NullableShape read(JsonReader in) throws IOException {
return ret;
}

throw new IOException(String.format("Failed deserialization for NullableShape: %d classes match result, expected 1. JSON: %s", match, jsonObject.toString()));
throw new IOException(String.format("Failed deserialization for NullableShape: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonObject.toString()));
}
}.nullSafe();
}
Expand Down Expand Up @@ -263,22 +266,25 @@ public Triangle getTriangle() throws ClassCastException {
public static void validateJsonObject(JsonObject jsonObj) throws IOException {
// validate oneOf schemas one by one
int validCount = 0;
ArrayList<String> errorMessages = new ArrayList<>();
// validate the json string with Quadrilateral
try {
Quadrilateral.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for Quadrilateral failed with `%s`.", e.getMessage()));
// continue to the next one
}
// validate the json string with Triangle
try {
Triangle.validateJsonObject(jsonObj);
validCount++;
} catch (Exception e) {
errorMessages.add(String.format("Deserialization for Triangle failed with `%s`.", e.getMessage()));
// continue to the next one
}
if (validCount != 1) {
throw new IOException(String.format("The JSON string is invalid for NullableShape with oneOf schemas: Quadrilateral, Triangle. %d class(es) match the result, expected 1. JSON: %s", validCount, jsonObj.toString()));
throw new IOException(String.format("The JSON string is invalid for NullableShape with oneOf schemas: Quadrilateral, Triangle. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonObj.toString()));
}
}

Expand Down
Loading

0 comments on commit 68360ca

Please sign in to comment.