Merge pull request #675 from johnjaylward/Iss-649-better-error-message

Updates value error messages to be consistent.
This commit is contained in:
Sean Leary 2022-03-24 20:32:31 -05:00 committed by GitHub
commit 6f92a3ab4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 80 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;

View File

@ -412,7 +412,7 @@ public class JSONArrayTest {
assertTrue("expected getBoolean to fail", false); assertTrue("expected getBoolean to fail", false);
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expected an exception message", assertEquals("Expected an exception message",
"JSONArray[4] is not a boolean.",e.getMessage()); "JSONArray[4] is not a boolean (class java.lang.String : hello).",e.getMessage());
} }
try { try {
jsonArray.get(-1); jsonArray.get(-1);
@ -426,42 +426,42 @@ public class JSONArrayTest {
assertTrue("expected getDouble to fail", false); assertTrue("expected getDouble to fail", false);
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expected an exception message", assertEquals("Expected an exception message",
"JSONArray[4] is not a double.",e.getMessage()); "JSONArray[4] is not a double (class java.lang.String : hello).",e.getMessage());
} }
try { try {
jsonArray.getInt(4); jsonArray.getInt(4);
assertTrue("expected getInt to fail", false); assertTrue("expected getInt to fail", false);
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expected an exception message", assertEquals("Expected an exception message",
"JSONArray[4] is not a int.",e.getMessage()); "JSONArray[4] is not a int (class java.lang.String : hello).",e.getMessage());
} }
try { try {
jsonArray.getJSONArray(4); jsonArray.getJSONArray(4);
assertTrue("expected getJSONArray to fail", false); assertTrue("expected getJSONArray to fail", false);
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expected an exception message", assertEquals("Expected an exception message",
"JSONArray[4] is not a JSONArray.",e.getMessage()); "JSONArray[4] is not a JSONArray (class java.lang.String : hello).",e.getMessage());
} }
try { try {
jsonArray.getJSONObject(4); jsonArray.getJSONObject(4);
assertTrue("expected getJSONObject to fail", false); assertTrue("expected getJSONObject to fail", false);
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expected an exception message", assertEquals("Expected an exception message",
"JSONArray[4] is not a JSONObject.",e.getMessage()); "JSONArray[4] is not a JSONObject (class java.lang.String : hello).",e.getMessage());
} }
try { try {
jsonArray.getLong(4); jsonArray.getLong(4);
assertTrue("expected getLong to fail", false); assertTrue("expected getLong to fail", false);
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expected an exception message", assertEquals("Expected an exception message",
"JSONArray[4] is not a long.",e.getMessage()); "JSONArray[4] is not a long (class java.lang.String : hello).",e.getMessage());
} }
try { try {
jsonArray.getString(5); jsonArray.getString(5);
assertTrue("expected getString to fail", false); assertTrue("expected getString to fail", false);
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expected an exception message", assertEquals("Expected an exception message",
"JSONArray[5] is not a String.",e.getMessage()); "JSONArray[5] is not a String (class java.math.BigDecimal : 0.002345).",e.getMessage());
} }
} }

View File

@ -158,7 +158,7 @@ public class JSONMLTest {
assertTrue("Expecting an exception", false); assertTrue("Expecting an exception", false);
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONArray[0] is not a String.", "JSONArray[0] is not a String (class org.json.JSONArray).",
e.getMessage()); e.getMessage());
} }
} }

View File

@ -1090,7 +1090,7 @@ public class JSONObjectTest {
fail("Expected an exception"); fail("Expected an exception");
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONObject[\"stringKey\"] is not a Boolean.", "JSONObject[\"stringKey\"] is not a Boolean (class java.lang.String : hello world!).",
e.getMessage()); e.getMessage());
} }
try { try {
@ -1106,7 +1106,7 @@ public class JSONObjectTest {
fail("Expected an exception"); fail("Expected an exception");
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONObject[\"trueKey\"] is not a string.", "JSONObject[\"trueKey\"] is not a string (class java.lang.Boolean : true).",
e.getMessage()); e.getMessage());
} }
try { try {
@ -1122,7 +1122,7 @@ public class JSONObjectTest {
fail("Expected an exception"); fail("Expected an exception");
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONObject[\"stringKey\"] is not a double.", "JSONObject[\"stringKey\"] is not a double (class java.lang.String : hello world!).",
e.getMessage()); e.getMessage());
} }
try { try {
@ -1138,7 +1138,7 @@ public class JSONObjectTest {
fail("Expected an exception"); fail("Expected an exception");
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONObject[\"stringKey\"] is not a float.", "JSONObject[\"stringKey\"] is not a float (class java.lang.String : hello world!).",
e.getMessage()); e.getMessage());
} }
try { try {
@ -1154,7 +1154,7 @@ public class JSONObjectTest {
fail("Expected an exception"); fail("Expected an exception");
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONObject[\"stringKey\"] is not a int.", "JSONObject[\"stringKey\"] is not a int (class java.lang.String : hello world!).",
e.getMessage()); e.getMessage());
} }
try { try {
@ -1170,7 +1170,7 @@ public class JSONObjectTest {
fail("Expected an exception"); fail("Expected an exception");
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONObject[\"stringKey\"] is not a long.", "JSONObject[\"stringKey\"] is not a long (class java.lang.String : hello world!).",
e.getMessage()); e.getMessage());
} }
try { try {
@ -1186,7 +1186,7 @@ public class JSONObjectTest {
fail("Expected an exception"); fail("Expected an exception");
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONObject[\"stringKey\"] is not a JSONArray.", "JSONObject[\"stringKey\"] is not a JSONArray (class java.lang.String : hello world!).",
e.getMessage()); e.getMessage());
} }
try { try {
@ -1202,7 +1202,7 @@ public class JSONObjectTest {
fail("Expected an exception"); fail("Expected an exception");
} catch (JSONException e) { } catch (JSONException e) {
assertEquals("Expecting an exception message", assertEquals("Expecting an exception message",
"JSONObject[\"stringKey\"] is not a JSONObject.", "JSONObject[\"stringKey\"] is not a JSONObject (class java.lang.String : hello world!).",
e.getMessage()); e.getMessage());
} }
} }