Updates value error messages to be consistent.

Provide both the type and value that failed conversion. Tries not to
"toString" large value types like Arrays or Maps. For those types it
will just output the type and not a value.
This commit is contained in:
John J. Aylward 2022-03-21 12:48:25 -04:00
parent 9abb35ad39
commit a642329314
3 changed files with 57 additions and 64 deletions

View File

@ -288,7 +288,7 @@ public class JSONArray implements Iterable<Object> {
.equalsIgnoreCase("true"))) { .equalsIgnoreCase("true"))) {
return true; return true;
} }
throw wrongValueFormatException(index, "boolean", null); throw wrongValueFormatException(index, "boolean", object, null);
} }
/** /**
@ -309,7 +309,7 @@ public class JSONArray implements Iterable<Object> {
try { try {
return Double.parseDouble(object.toString()); return Double.parseDouble(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(index, "double", e); throw wrongValueFormatException(index, "double", object, e);
} }
} }
@ -331,7 +331,7 @@ public class JSONArray implements Iterable<Object> {
try { try {
return Float.parseFloat(object.toString()); return Float.parseFloat(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(index, "float", e); throw wrongValueFormatException(index, "float", object, e);
} }
} }
@ -353,7 +353,7 @@ public class JSONArray implements Iterable<Object> {
} }
return JSONObject.stringToNumber(object.toString()); return JSONObject.stringToNumber(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(index, "number", e); throw wrongValueFormatException(index, "number", object, e);
} }
} }
@ -378,7 +378,7 @@ public class JSONArray implements Iterable<Object> {
// If it did, I would re-implement this with the Enum.valueOf // If it did, I would re-implement this with the Enum.valueOf
// method and place any thrown exception in the JSONException // method and place any thrown exception in the JSONException
throw wrongValueFormatException(index, "enum of type " throw wrongValueFormatException(index, "enum of type "
+ JSONObject.quote(clazz.getSimpleName()), null); + JSONObject.quote(clazz.getSimpleName()), opt(index), null);
} }
return val; return val;
} }
@ -441,7 +441,7 @@ public class JSONArray implements Iterable<Object> {
try { try {
return Integer.parseInt(object.toString()); return Integer.parseInt(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(index, "int", e); throw wrongValueFormatException(index, "int", object, e);
} }
} }
@ -460,7 +460,7 @@ public class JSONArray implements Iterable<Object> {
if (object instanceof JSONArray) { if (object instanceof JSONArray) {
return (JSONArray) object; return (JSONArray) object;
} }
throw wrongValueFormatException(index, "JSONArray", null); throw wrongValueFormatException(index, "JSONArray", object, null);
} }
/** /**
@ -478,7 +478,7 @@ public class JSONArray implements Iterable<Object> {
if (object instanceof JSONObject) { if (object instanceof JSONObject) {
return (JSONObject) object; return (JSONObject) object;
} }
throw wrongValueFormatException(index, "JSONObject", null); throw wrongValueFormatException(index, "JSONObject", object, null);
} }
/** /**
@ -499,7 +499,7 @@ public class JSONArray implements Iterable<Object> {
try { try {
return Long.parseLong(object.toString()); return Long.parseLong(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(index, "long", e); throw wrongValueFormatException(index, "long", object, e);
} }
} }
@ -517,7 +517,7 @@ public class JSONArray implements Iterable<Object> {
if (object instanceof String) { if (object instanceof String) {
return (String) object; return (String) object;
} }
throw wrongValueFormatException(index, "String", null); throw wrongValueFormatException(index, "String", object, null);
} }
/** /**
@ -1464,6 +1464,7 @@ public class JSONArray implements Iterable<Object> {
* &nbsp;<small>(right bracket)</small>. * &nbsp;<small>(right bracket)</small>.
* @throws JSONException if a called function fails * @throws JSONException if a called function fails
*/ */
@SuppressWarnings("resource")
public String toString(int indentFactor) throws JSONException { public String toString(int indentFactor) throws JSONException {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) { synchronized (sw.getBuffer()) {
@ -1513,6 +1514,7 @@ public class JSONArray implements Iterable<Object> {
* @return The writer. * @return The writer.
* @throws JSONException if a called function fails or unable to write * @throws JSONException if a called function fails or unable to write
*/ */
@SuppressWarnings("resource")
public Writer write(Writer writer, int indentFactor, int indent) public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException { throws JSONException {
try { try {
@ -1680,22 +1682,6 @@ public class JSONArray implements Iterable<Object> {
} }
} }
/**
* Create a new JSONException in a common format for incorrect conversions.
* @param idx index of the item
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
int idx,
String valueType,
Throwable cause) {
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + "."
, cause);
}
/** /**
* Create a new JSONException in a common format for incorrect conversions. * Create a new JSONException in a common format for incorrect conversions.
* @param idx index of the item * @param idx index of the item
@ -1708,8 +1694,19 @@ public class JSONArray implements Iterable<Object> {
String valueType, String valueType,
Object value, Object value,
Throwable cause) { Throwable cause) {
if(value == null) {
return new JSONException( return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + " (" + value + ")." "JSONArray[" + idx + "] is not a " + valueType + " (null)."
, cause);
}
// don't try to toString collections or known object types that could be large.
if(value instanceof Map || value instanceof Iterable || value instanceof JSONObject) {
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + " (" + value.getClass() + ")."
, cause);
}
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + " (" + value.getClass() + " : " + value + ")."
, cause); , cause);
} }

View File

@ -609,7 +609,7 @@ public class JSONObject {
// JSONException should really take a throwable argument. // JSONException should really take a throwable argument.
// If it did, I would re-implement this with the Enum.valueOf // If it did, I would re-implement this with the Enum.valueOf
// method and place any thrown exception in the JSONException // method and place any thrown exception in the JSONException
throw wrongValueFormatException(key, "enum of type " + quote(clazz.getSimpleName()), null); throw wrongValueFormatException(key, "enum of type " + quote(clazz.getSimpleName()), opt(key), null);
} }
return val; return val;
} }
@ -635,7 +635,7 @@ public class JSONObject {
.equalsIgnoreCase("true"))) { .equalsIgnoreCase("true"))) {
return true; return true;
} }
throw wrongValueFormatException(key, "Boolean", null); throw wrongValueFormatException(key, "Boolean", object, null);
} }
/** /**
@ -697,7 +697,7 @@ public class JSONObject {
try { try {
return Double.parseDouble(object.toString()); return Double.parseDouble(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(key, "double", e); throw wrongValueFormatException(key, "double", object, e);
} }
} }
@ -719,7 +719,7 @@ public class JSONObject {
try { try {
return Float.parseFloat(object.toString()); return Float.parseFloat(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(key, "float", e); throw wrongValueFormatException(key, "float", object, e);
} }
} }
@ -741,7 +741,7 @@ public class JSONObject {
} }
return stringToNumber(object.toString()); return stringToNumber(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(key, "number", e); throw wrongValueFormatException(key, "number", object, e);
} }
} }
@ -763,7 +763,7 @@ public class JSONObject {
try { try {
return Integer.parseInt(object.toString()); return Integer.parseInt(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(key, "int", e); throw wrongValueFormatException(key, "int", object, e);
} }
} }
@ -781,7 +781,7 @@ public class JSONObject {
if (object instanceof JSONArray) { if (object instanceof JSONArray) {
return (JSONArray) object; return (JSONArray) object;
} }
throw wrongValueFormatException(key, "JSONArray", null); throw wrongValueFormatException(key, "JSONArray", object, null);
} }
/** /**
@ -798,7 +798,7 @@ public class JSONObject {
if (object instanceof JSONObject) { if (object instanceof JSONObject) {
return (JSONObject) object; return (JSONObject) object;
} }
throw wrongValueFormatException(key, "JSONObject", null); throw wrongValueFormatException(key, "JSONObject", object, null);
} }
/** /**
@ -819,7 +819,7 @@ public class JSONObject {
try { try {
return Long.parseLong(object.toString()); return Long.parseLong(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw wrongValueFormatException(key, "long", e); throw wrongValueFormatException(key, "long", object, e);
} }
} }
@ -875,7 +875,7 @@ public class JSONObject {
if (object instanceof String) { if (object instanceof String) {
return (String) object; return (String) object;
} }
throw wrongValueFormatException(key, "string", null); throw wrongValueFormatException(key, "string", object, null);
} }
/** /**
@ -1201,13 +1201,12 @@ public class JSONObject {
} }
if (exact) { if (exact) {
return new BigDecimal(((Number)val).doubleValue()); return new BigDecimal(((Number)val).doubleValue());
}else { }
// use the string constructor so that we maintain "nice" values for doubles and floats // use the string constructor so that we maintain "nice" values for doubles and floats
// the double constructor will translate doubles to "exact" values instead of the likely // the double constructor will translate doubles to "exact" values instead of the likely
// intended representation // intended representation
return new BigDecimal(val.toString()); return new BigDecimal(val.toString());
} }
}
if (val instanceof Long || val instanceof Integer if (val instanceof Long || val instanceof Integer
|| val instanceof Short || val instanceof Byte){ || val instanceof Short || val instanceof Byte){
return new BigDecimal(((Number) val).longValue()); return new BigDecimal(((Number) val).longValue());
@ -2021,6 +2020,7 @@ public class JSONObject {
* A String * A String
* @return A String correctly formatted for insertion in a JSON text. * @return A String correctly formatted for insertion in a JSON text.
*/ */
@SuppressWarnings("resource")
public static String quote(String string) { public static String quote(String string) {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) { synchronized (sw.getBuffer()) {
@ -2141,7 +2141,7 @@ public class JSONObject {
} else if (valueThis instanceof Number && valueOther instanceof Number) { } else if (valueThis instanceof Number && valueOther instanceof Number) {
if (!isNumberSimilar((Number)valueThis, (Number)valueOther)) { if (!isNumberSimilar((Number)valueThis, (Number)valueOther)) {
return false; return false;
}; }
} else if (!valueThis.equals(valueOther)) { } else if (!valueThis.equals(valueOther)) {
return false; return false;
} }
@ -2409,6 +2409,7 @@ public class JSONObject {
* @throws JSONException * @throws JSONException
* If the object contains an invalid number. * If the object contains an invalid number.
*/ */
@SuppressWarnings("resource")
public String toString(int indentFactor) throws JSONException { public String toString(int indentFactor) throws JSONException {
StringWriter w = new StringWriter(); StringWriter w = new StringWriter();
synchronized (w.getBuffer()) { synchronized (w.getBuffer()) {
@ -2502,10 +2503,8 @@ public class JSONObject {
if (objectsRecord != null) { if (objectsRecord != null) {
return new JSONObject(object, objectsRecord); return new JSONObject(object, objectsRecord);
} }
else {
return new JSONObject(object); return new JSONObject(object);
} }
}
catch (JSONException exception) { catch (JSONException exception) {
throw exception; throw exception;
} catch (Exception exception) { } catch (Exception exception) {
@ -2527,6 +2526,7 @@ public class JSONObject {
return this.write(writer, 0, 0); return this.write(writer, 0, 0);
} }
@SuppressWarnings("resource")
static final Writer writeValue(Writer writer, Object value, static final Writer writeValue(Writer writer, Object value,
int indentFactor, int indent) throws JSONException, IOException { int indentFactor, int indent) throws JSONException, IOException {
if (value == null || value.equals(null)) { if (value == null || value.equals(null)) {
@ -2604,6 +2604,7 @@ public class JSONObject {
* @throws JSONException if a called function has an error or a write error * @throws JSONException if a called function has an error or a write error
* occurs * occurs
*/ */
@SuppressWarnings("resource")
public Writer write(Writer writer, int indentFactor, int indent) public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException { throws JSONException {
try { try {
@ -2686,22 +2687,6 @@ public class JSONObject {
return results; return results;
} }
/**
* Create a new JSONException in a common format for incorrect conversions.
* @param key name of the key
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
String key,
String valueType,
Throwable cause) {
return new JSONException(
"JSONObject[" + quote(key) + "] is not a " + valueType + "."
, cause);
}
/** /**
* Create a new JSONException in a common format for incorrect conversions. * Create a new JSONException in a common format for incorrect conversions.
* @param key name of the key * @param key name of the key
@ -2714,8 +2699,20 @@ public class JSONObject {
String valueType, String valueType,
Object value, Object value,
Throwable cause) { Throwable cause) {
if(value == null) {
return new JSONException( return new JSONException(
"JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value + ")." "JSONObject[" + quote(key) + "] is not a " + valueType + " (null)."
, cause);
}
// don't try to toString collections or known object types that could be large.
if(value instanceof Map || value instanceof Iterable || value instanceof JSONObject) {
return new JSONException(
"JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value.getClass() + ")."
, cause);
}
return new JSONException(
"JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value.getClass() + " : " + value + ")."
, cause); , cause);
} }

View File

@ -26,7 +26,6 @@ SOFTWARE.
import java.io.Reader; import java.io.Reader;
import java.io.StringReader; import java.io.StringReader;
import java.lang.reflect.Method;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Iterator; import java.util.Iterator;