-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Start throwing common errors
(box/box-codegen#516)
(#147)
- Loading branch information
1 parent
95391c9
commit d12bbb7
Showing
20 changed files
with
370 additions
and
538 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
{ "engineHash": "62c749a", "specHash": "fc01415", "version": "0.1.0" } | ||
{ "engineHash": "74a3b04", "specHash": "fc01415", "version": "0.1.0" } |
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import Foundation | ||
#if canImport(FoundationNetworking) | ||
import FoundationNetworking | ||
#endif | ||
|
||
/// Describes API request related errors. | ||
public class BoxAPIError: BoxSDKError { | ||
/// The request information | ||
public let requestInfo: RequestInfo | ||
/// The response information | ||
public let responseInfo: ResponseInfo | ||
|
||
/// Initializer | ||
/// | ||
/// - Parameters: | ||
/// - message: The error message | ||
/// - requestInfo: The request information | ||
/// - responseInfo: The response information | ||
/// - timestamp: The timestamp of the error | ||
/// - error: The underlying error which caused this error, if any. | ||
public init(message: String, requestInfo: RequestInfo, responseInfo: ResponseInfo, timestamp: Date? = nil, error: Error? = nil) { | ||
self.requestInfo = requestInfo | ||
self.responseInfo = responseInfo | ||
|
||
super.init(message: message, timestamp: timestamp, error: error, name: "BoxAPIError") | ||
} | ||
|
||
/// Gets a dictionary representing the APIError. | ||
/// | ||
/// - Returns: A dictionary representing the APIError. | ||
override public func getDictionary() -> [String: Any] { | ||
var dict = super.getDictionary() | ||
dict["request"] = requestInfo.getDictionary() | ||
dict["response"] = responseInfo.getDictionary() | ||
return dict | ||
} | ||
|
||
} | ||
|
||
extension BoxAPIError { | ||
/// Initializer | ||
/// | ||
/// - Parameters: | ||
/// - fromConversation: Represents a data combined with the request and the corresponding response. | ||
convenience init(fromConversation conversation: FetchConversation, message: String? = nil) { | ||
let requestHeaders = conversation.options.headers.compactMapValues { $0?.paramValue } | ||
let requestInfo = RequestInfo( | ||
method: conversation.options.method.rawValue, | ||
url: conversation.url, | ||
queryParams: conversation.options.headers.compactMapValues { $0?.paramValue }, | ||
headers: requestHeaders, | ||
body: requestHeaders[HTTPHeaderKey.contentType, default: ""].paramValue == HTTPHeaderContentTypeValue.urlEncoded | ||
? try? conversation.options.data?.toUrlParams() | ||
: try? Utils.Strings.from(data: conversation.options.data?.toJson() ?? Data()) | ||
) | ||
|
||
var body: SerializedData? | ||
var json: [String: Any]? | ||
if case let .data(data) = conversation.responseType { | ||
body = SerializedData(data: data) | ||
json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] | ||
} | ||
let responseInfo = ResponseInfo( | ||
statusCode: conversation.urlResponse.statusCode, | ||
headers: conversation.urlResponse.allHeaderFields as? [String: String] ?? [:], | ||
body: body, | ||
rawBody: try? Utils.Strings.from(data: body?.toJson() ?? Data()), | ||
code: json?["code"] as? String, | ||
contextInfo: json?["context_info"] as? [String: Any], | ||
requestId: json?["request_id"] as? String, | ||
helperUrl: json?["help_url"] as? String, | ||
message: json?["message"] as? String | ||
) | ||
|
||
self.init( | ||
message: message ?? Self.createMessage(fromResponse: responseInfo), | ||
requestInfo: requestInfo, | ||
responseInfo: responseInfo | ||
) | ||
} | ||
|
||
/// Gets a formatted user-friendly message based on the `ResponseDescription` | ||
/// | ||
/// - Returns: Formatted user-friendly message based on the `ResponseDescription` | ||
static func createMessage(fromResponse response: ResponseInfo) -> String { | ||
var message = "The API returned an unexpected response: " | ||
message += "[\(response.statusCode) \(HTTPURLResponse.localizedString(forStatusCode: response.statusCode).capitalized)" | ||
|
||
if let requestId = response.requestId { | ||
message += " | \(requestId)] " | ||
} | ||
else { | ||
message += "]" | ||
} | ||
|
||
if let code = response.code { | ||
message += " \(code)" | ||
} | ||
|
||
if let shortMessage = response.message { | ||
message += " - \(shortMessage)" | ||
} | ||
|
||
return message | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import Foundation | ||
|
||
/// Describes network related errors. | ||
public class BoxNetworkError: BoxSDKError { | ||
|
||
/// Initializer | ||
/// | ||
/// - Parameters: | ||
/// - message: Error message | ||
/// - error: The underlying error which caused this error, if any. | ||
public init(message: String, timestamp: Date? = nil, error: Error? = nil) { | ||
super.init(message: message, timestamp: timestamp, error: error, name: "BoxNetworkError") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import Foundation | ||
|
||
/// Describes general errors | ||
public class BoxSDKError: Error { | ||
/// The error message | ||
public let message: String | ||
/// The timestamp of the error | ||
public let timestamp: Date | ||
/// The underlying error which caused this error | ||
public let error: Error? | ||
/// The name of the error | ||
public let name: String | ||
|
||
public init(message: String, timestamp: Date? = nil, error: Error? = nil, name: String = "BoxSDKError") { | ||
self.message = message | ||
self.timestamp = timestamp ?? Date() | ||
self.error = error | ||
self.name = name | ||
} | ||
|
||
/// Gets a dictionary representing the BoxSDKError. | ||
/// | ||
/// - Returns: A dictionary representing the BoxSDKError. | ||
public func getDictionary() -> [String: Any] { | ||
var dict = [String: Any]() | ||
dict["name"] = name | ||
dict["timestamp"] = Utils.Dates.dateTimeToString(dateTime: timestamp) | ||
dict["message"] = message.description | ||
dict["error"] = error?.localizedDescription | ||
return dict | ||
} | ||
|
||
} | ||
|
||
/// Extension for `CustomStringConvertible` conformance | ||
extension BoxSDKError: CustomStringConvertible { | ||
/// Provides error JSON string if found. | ||
public var description: String { | ||
guard | ||
let encodedData = try? JSONSerialization.data(withJSONObject: getDictionary(), options: [.prettyPrinted, .sortedKeys]), | ||
let JSONString = String(data: encodedData, encoding: .utf8) | ||
else { | ||
return "<Unparsed Error>" | ||
} | ||
return JSONString.replacingOccurrences(of: "\\", with: "") | ||
} | ||
} |
Oops, something went wrong.