Skip to content

Commit 738eacd

Browse files
committed
Convert the json error cases to more cross platform NSErrors
This more closely mimics the darwin version of the errors returned from parsing.
1 parent ed41944 commit 738eacd

File tree

2 files changed

+45
-52
lines changed

2 files changed

+45
-52
lines changed

Foundation/NSJSONSerialization.swift

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,6 @@ public struct NSJSONWritingOptions : OptionSetType {
2424
public static let PrettyPrinted = NSJSONWritingOptions(rawValue: 1 << 0)
2525
}
2626

27-
enum NSJSONSerializationError: ErrorType {
28-
typealias Position = String.UnicodeScalarIndex.Distance
29-
30-
case InvalidStringEncoding
31-
case NotAnArrayOrObject
32-
case UnterminatedString(Position)
33-
case MissingObjectKey(Position)
34-
case InvalidValue(Position)
35-
case MissingTrailingSurrogate(Position)
36-
case InvalidEscapeSequence(Position)
37-
case BadlyFormedArray(Position)
38-
case UnexpectedEndOfFile
39-
}
4027

4128
/* A class for converting JSON to Foundation/Swift objects and converting Foundation/Swift objects to JSON.
4229

@@ -69,7 +56,9 @@ public class NSJSONSerialization : NSObject {
6956
public class func JSONObjectWithData(data: NSData, options opt: NSJSONReadingOptions) throws -> AnyObject {
7057

7158
guard let string = NSString(data: data, encoding: detectEncoding(data)) else {
72-
throw NSJSONSerializationError.InvalidStringEncoding
59+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
60+
"NSDebugDescription" : "Unable to convert data to a string using the detected encoding. The data may be corrupt."
61+
])
7362
}
7463
let result = _NSObjectRepresentableBridge(try JSONObjectWithString(string._swiftObject))
7564
return result
@@ -99,7 +88,9 @@ internal extension NSJSONSerialization {
9988
else if let (array, _) = try JSONDeserializer.parseArray(parser) {
10089
return array
10190
}
102-
throw NSJSONSerializationError.NotAnArrayOrObject
91+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
92+
"NSDebugDescription" : "JSON text did not start with array or object and option to allow fragments not set."
93+
])
10394
}
10495
}
10596

@@ -227,7 +218,9 @@ private struct JSONDeserializer {
227218
static func consumeScalar(scalar: UnicodeScalar, input: UnicodeParser) throws -> UnicodeParser? {
228219
switch takeScalar(input) {
229220
case nil:
230-
throw NSJSONSerializationError.UnexpectedEndOfFile
221+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
222+
"NSDebugDescription" : "Unexpected end of file during JSON parse."
223+
])
231224
case let (taken, parser)? where taken == scalar:
232225
return parser
233226
default:
@@ -296,18 +289,24 @@ private struct JSONDeserializer {
296289
index = newParser.index
297290
}
298291
else {
299-
throw NSJSONSerializationError.InvalidEscapeSequence(parser.distanceFromStart - 1)
292+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
293+
"NSDebugDescription" : "Invalid unicode escape sequence at position \(parser.distanceFromStart - 1)"
294+
])
300295
}
301296
default:
302297
value.append(scalar)
303298
}
304299
}
305-
throw NSJSONSerializationError.UnterminatedString(input.distanceFromStart)
300+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
301+
"NSDebugDescription" : "Unexpected end of file during string parse."
302+
])
306303
}
307304

308305
static func parseEscapeSequence(input: UnicodeParser) throws -> (UnicodeScalar, UnicodeParser)? {
309306
guard let (scalar, parser) = takeScalar(input) else {
310-
throw NSJSONSerializationError.UnexpectedEndOfFile
307+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
308+
"NSDebugDescription" : "Early end of unicode escape sequence around character"
309+
])
311310
}
312311
switch scalar {
313312
case UnicodeScalar(0x22): // " quotation mark U+0022
@@ -344,7 +343,9 @@ private struct JSONDeserializer {
344343
}
345344

346345
guard let (trailCodeUnit, finalParser) = try consumeSequence("\\u", input: parser).flatMap(parseCodeUnit) where UTF16.isTrailSurrogate(trailCodeUnit) else {
347-
throw NSJSONSerializationError.MissingTrailingSurrogate(parser.distanceFromStart)
346+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
347+
"NSDebugDescription" : "Unable to convert hex escape sequence (no high character) to UTF8-encoded character at position \(parser.distanceFromStart)"
348+
])
348349
}
349350

350351
var utf = UTF16()
@@ -441,13 +442,19 @@ private struct JSONDeserializer {
441442

442443
static func parseObjectMember(input: UnicodeParser) throws -> (String, Any, UnicodeParser)? {
443444
guard let (name, parser) = try parseString(input) else {
444-
throw NSJSONSerializationError.MissingObjectKey(input.distanceFromStart)
445+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
446+
"NSDebugDescription" : "Missing object key at location \(input.distanceFromStart)"
447+
])
445448
}
446449
guard let separatorParser = try consumeStructure(StructureScalar.NameSeparator, input: parser) else {
447-
throw NSJSONSerializationError.InvalidValue(parser.distanceFromStart)
450+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
451+
"NSDebugDescription" : "Invalid value at location \(input.distanceFromStart)"
452+
])
448453
}
449454
guard let (value, finalParser) = try parseValue(separatorParser) else {
450-
throw NSJSONSerializationError.InvalidValue(separatorParser.distanceFromStart)
455+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
456+
"NSDebugDescription" : "Invalid value at location \(input.distanceFromStart)"
457+
])
451458
}
452459

453460
return (name, value, finalParser)
@@ -476,10 +483,14 @@ private struct JSONDeserializer {
476483
continue
477484
}
478485
else {
479-
throw NSJSONSerializationError.BadlyFormedArray(newParser.distanceFromStart)
486+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
487+
"NSDebugDescription" : "Unexpected end of file while parsing array at location \(input.distanceFromStart)"
488+
])
480489
}
481490
}
482-
throw NSJSONSerializationError.InvalidValue(parser.distanceFromStart)
491+
throw NSError(domain: NSCocoaErrorDomain, code: NSCocoaError.PropertyListReadCorruptError.rawValue, userInfo: [
492+
"NSDebugDescription" : "Unexpected end of file while parsing array at location \(input.distanceFromStart)"
493+
])
483494
}
484495
}
485496
}

TestFoundation/TestNSJSONSerialization.swift

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,8 @@ extension TestNSJSONSerialization {
229229
do {
230230
try NSJSONSerialization.JSONObjectWithString(subject)
231231
XCTFail("Expected error: UnterminatedString")
232-
} catch let NSJSONSerializationError.UnterminatedString(index){
233-
XCTAssertEqual(index, 1)
234232
} catch {
235-
XCTFail("Unexpected error: \(error)")
233+
// Passing case; the object as unterminated
236234
}
237235
}
238236

@@ -242,10 +240,8 @@ extension TestNSJSONSerialization {
242240
do {
243241
try NSJSONSerialization.JSONObjectWithString(subject)
244242
XCTFail("Expected error: Missing key for value")
245-
} catch let NSJSONSerializationError.MissingObjectKey(index){
246-
XCTAssertEqual(index, 1)
247243
} catch {
248-
XCTFail("Unexpected error: \(error)")
244+
// Passing case; the key was missing for a value
249245
}
250246
}
251247

@@ -255,10 +251,8 @@ extension TestNSJSONSerialization {
255251
do {
256252
try NSJSONSerialization.JSONObjectWithString(subject)
257253
XCTFail("Expected error: Unexpected end of file")
258-
} catch NSJSONSerializationError.UnexpectedEndOfFile {
259-
// Success
260254
} catch {
261-
XCTFail("Unexpected error: \(error)")
255+
// Success
262256
}
263257
}
264258

@@ -268,10 +262,8 @@ extension TestNSJSONSerialization {
268262
do {
269263
try NSJSONSerialization.JSONObjectWithString(subject)
270264
XCTFail("Expected error: Invalid value")
271-
} catch let NSJSONSerializationError.InvalidValue(index){
272-
XCTAssertEqual(index, 9)
273265
} catch {
274-
XCTFail("Unexpected error: \(error)")
266+
// Passing case; the value is invalid
275267
}
276268
}
277269

@@ -281,10 +273,8 @@ extension TestNSJSONSerialization {
281273
do {
282274
try NSJSONSerialization.JSONObjectWithString(subject)
283275
XCTFail("Expected error: Invalid value")
284-
} catch let NSJSONSerializationError.InvalidValue(index){
285-
XCTAssertEqual(index, 10)
286276
} catch {
287-
XCTFail("Unexpected error: \(error)")
277+
// passing case the value is invalid
288278
}
289279
}
290280

@@ -294,10 +284,8 @@ extension TestNSJSONSerialization {
294284
do {
295285
try NSJSONSerialization.JSONObjectWithString(subject)
296286
XCTFail("Expected error: Invalid value")
297-
} catch let NSJSONSerializationError.InvalidValue(index){
298-
XCTAssertEqual(index, 1)
299287
} catch {
300-
XCTFail("Unexpected error: \(error)")
288+
// Passing case; the element in the array is missing
301289
}
302290
}
303291

@@ -307,10 +295,8 @@ extension TestNSJSONSerialization {
307295
do {
308296
try NSJSONSerialization.JSONObjectWithString(subject)
309297
XCTFail("Expected error: Badly formed array")
310-
} catch let NSJSONSerializationError.BadlyFormedArray(index){
311-
XCTAssertEqual(index, 2)
312298
} catch {
313-
XCTFail("Unexpected error: \(error)")
299+
// Passing case; the array is malformed
314300
}
315301
}
316302

@@ -320,10 +306,8 @@ extension TestNSJSONSerialization {
320306
do {
321307
try NSJSONSerialization.JSONObjectWithString(subject)
322308
XCTFail("Expected error: Invalid escape sequence")
323-
} catch let NSJSONSerializationError.InvalidEscapeSequence(index){
324-
XCTAssertEqual(index, 2, "\(index)")
325309
} catch {
326-
XCTFail("Unexpected error: \(error)")
310+
// Passing case; the escape sequence is invalid
327311
}
328312
}
329313

@@ -332,10 +316,8 @@ extension TestNSJSONSerialization {
332316
do {
333317
try NSJSONSerialization.JSONObjectWithString(subject) as? [String]
334318
XCTFail("Expected error: Missing Trailing Surrogate")
335-
} catch let NSJSONSerializationError.MissingTrailingSurrogate(index) {
336-
XCTAssertEqual(index, 8)
337319
} catch {
338-
XCTFail("Unexpected error: \(error)")
320+
// Passing case; the unicode character is malformed
339321
}
340322
}
341323
}

0 commit comments

Comments
 (0)