MarcusOtter / APOD.Net

An unofficial .NET wrapper for NASA's Astronomy Picture of the Day API.
https://marcusotter.github.io/APOD.Net/
MIT License
9 stars 2 forks source link

Deserialize both error types #16

Closed MarcusOtter closed 4 years ago

MarcusOtter commented 4 years ago

The API can return two different JSON error objects:

API error examples

Type 1:

{
  "error": {
    "code": "API_KEY_INVALID",
    "message": "An invalid api_key was supplied. Get one at https://api.nasa.gov:443"
  }
}

Type 2:

{
  "code": 400,
  "msg": "Date must be between Jun 16, 1995 and Oct 30, 2019.",
  "service_version": "v1"
}

I need to deserialize both of these and then serialize into an ApodError and I never which error type I am going to get. All I know is that Type 1 errors should be more common since most of the Type 2 errors are related to user input, which is checked by the ErrorHandler before making the HTTP request. While I could make DTOs for the two errors (making it 3 classes, since Type 1 errors have nested objects), naming these anything remotely informative is an impossible task. Therefore, it's probably best to deserialize dynamically and check if the properties are null. For example, I could write a method called ErrorContainsServiceVersion(HttpResponseMessage) which returns a bool if the deserialized object["service_version"] is null.

ApodError example in JSON

{
  "errorCode": "ApiKeyInvalid",
  "errorMessage": "An invalid api_key was supplied. Get one at https://api.nasa.gov:443"
}

Bonus

The API also returns HTML content for timeout errors instead of JSON (yes, with this indentation). Luckily, I can check if the content type is text/html instead of the usual application/json for the timeout errors since they are the only type of error (that I've found) that return HTML.

<!DOCTYPE html>
        <html>
          <head>
                <meta name=""viewport"" content=""width=device-width, initial-scale=1"" >
                <meta charset=""utf-8"" >
                <title>Application Error</title>
                <style media=""screen"" >
                  html,body,iframe {
                        margin: 0;
                        padding: 0;
                  }
                  html,body {
                        height: 100%;
                        overflow: hidden;
                  }
                  iframe {
                        width: 100%;
                        height: 100%;
                        border: 0;
                  }
                </style>
          </head>
          <body>
                <iframe src=""//www.herokucdn.com/error-pages/application-error.html"" ></iframe>
          </body>
        </html>