wvteijlingen / Spine

A Swift library for working with JSON:API APIs. It supports mapping to custom model classes, fetching, advanced querying, linking and persisting.
MIT License
264 stars 109 forks source link

SpineError Handling #182

Open sachin-sat opened 7 years ago

sachin-sat commented 7 years ago

Hi There,

How to parse error in Spine? I couldn’t parse in failure block. there is only “error.localizedDescription” it also prints “"The operation couldn’t be completed. (Spine.SpineError error 0.)"”

Here is the error when i try to print error

▿ SpineError
  ▿ serverError : 2 elements
    - .0 : 500
    ▿ .1 : Optional<Array<APIError>>
      ▿ some : 1 element
        ▿ 0 : APIError
          ▿ id : Optional<String>
            - some : "F000"
          - status : nil
          - code : nil
          ▿ title : Optional<String>
            - some : "General Exception"
          - detail : nil
          - sourcePointer : nil
          - sourceParameter : nil
          - meta : nil
markst commented 7 years ago

Hey @sachin-sat, here's an example which might help you out:

}.onFailure { [unowned sender, weak self] (spineError) in

    sender.isEnabled = true
    sender.hideLoadingView()

    ErrorHandler.handleSpineError(error: spineError)

    switch spineError {
    case .serverError(_, let apiErrors):
        DispatchQueue.main.async {

            if let handled = self?.fittingInformationViewController?.fittingInformationView.handleAPIError(apiErrors: apiErrors!),
                handled == true {

                // Scroll user to first index:
                if self?.pageController?.selectedIndex != 0 {
                    self?.pageController?.selectedIndex = 0
                }
            }
        }
        break
    default: break
    }
sachin-sat commented 7 years ago

What does your ErrorHandler.handleSpineError do? Could you elaborate it? thanks in advance.

@markst

sachin-sat commented 7 years ago

Anybody please?

markst commented 7 years ago

@sachin-sat ErrorHandler is my own class written for convenience, here's some example:

import Spine

class ErrorHandler {

    class func handleSpineError(error: SpineError) {

        var message: String?
        var properties: [NSObject : AnyObject]?

        switch error {
        case .serverError(let statusCode, let apiErrors):
            if let firstError = apiErrors?.first {
                message = firstError.detail

                if statusCode == 401 {
                    /*
                    Session.clearCurrent()
                    NotificationCenter.default.post(name: Constants.Application.Notifications.HTTP401ResponseNotification.name,
                                                    object: nil)
                     */
                }
            } else {
                message = "Unknown server error"
            }
        case .networkError(let networkError):
            message = networkError.localizedDescription
            properties = networkError.userInfo as [NSObject : AnyObject]?
        case .serializerError(let serializerError):

            switch serializerError {
            case .invalidDocumentStructure:
                message = "The given JSON is not a dictionary (hash)."
            case .topLevelEntryMissing:
                message = "None of 'data', 'errors', or 'meta' is present in the top level."
            case .topLevelDataAndErrorsCoexist:
                message = "Top level 'data' and 'errors' coexist in the same document."
            case .invalidResourceStructure:
                    message = "The given JSON is not a dictionary (hash)."
            case .resourceTypeMissing:
                message = "'Type' field is missing from resource JSON."
            case .resourceTypeUnregistered(let resourceType):
                message = "The resource type: \(resourceType) has not been registered to Spine."
            case .resourceIDMissing:
                message = "'ID' field is missing from resource JSON."
            /// Error occurred in NSJSONSerialization
            case .jsonSerializationError(let error):
                message = error.localizedDescription
            default:
            message = "Unknown Server Error" // Treating all serializer errors as internal errors until server correctly returns JSON:API formatted errors.
            }
        case .nextPageNotAvailable:
            message = "Next Page Not Available"
        case .previousPageNotAvailable:
            message = "Previous Page Not Available"
        case .unknownError:
            message = "Unknown Error"
        case .resourceNotFound:
            message = "Resource Not Found"
        default:
            print("Expected error to be be .ServerError")
            message = "Unhandled Error"
        }

        ErrorHandler.showErrorView(with: message!)

        #if ADHOC
            NSLog("ErrorHandler.handleSpineError with message: \(message)")
        #endif
        /*
        DefaultTracker.trackError(errorMessage: message, properties: properties)
         */
    }
sachin-sat commented 7 years ago

@markst
Will check it and let you know. Thanks.