Compare commits

...

6 Commits

Author SHA1 Message Date
Sean Leary
88ca19042b Merge pull request #684 from stleary/pipeline-fix-1
pipeline-fix-1 remove v7 build from pipeline
2022-08-20 08:33:23 -05:00
stleary
b4036e6a8e pipeline-fix-1 remove v7 build from pipeline 2022-08-13 12:50:10 -05:00
Sean Leary
6f92a3ab4e Merge pull request #675 from johnjaylward/Iss-649-better-error-message
Updates value error messages to be consistent.
2022-03-24 20:32:31 -05:00
John J. Aylward
beae279b21 Updates tests to have updated message expectations 2022-03-21 13:06:19 -04:00
John J. Aylward
a642329314 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.
2022-03-21 12:48:25 -04:00
Sean Leary
9abb35ad39 Update RELEASES.md 2022-03-20 09:34:12 -05:00
8 changed files with 75 additions and 82 deletions

View File

@@ -42,7 +42,7 @@ jobs:
strategy: strategy:
matrix: matrix:
# build against supported Java LTS versions: # build against supported Java LTS versions:
java: [ 1.7, 8, 11 ] java: [ 8, 11 ]
name: Java ${{ matrix.java }} name: Java ${{ matrix.java }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View File

@@ -5,7 +5,7 @@ and artifactId "json". For example:
[https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav](https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav) [https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav](https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav)
~~~ ~~~
20220320 Recent commits 20220320 Wrap StackOverflow with JSONException
20211205 Recent commits and some bug fixes for similar() 20211205 Recent commits and some bug fixes for similar()

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(
"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( return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + " (" + value + ")." "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,12 +1201,11 @@ 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
// the double constructor will translate doubles to "exact" values instead of the likely
// intended representation
return new BigDecimal(val.toString());
} }
// 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
// intended representation
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){
@@ -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,9 +2503,7 @@ 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;
@@ -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(
"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( return new JSONException(
"JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value + ")." "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());
} }
} }