Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combine error callbacks #377

Merged
merged 4 commits into from Feb 21, 2019
Merged

Combine error callbacks #377

merged 4 commits into from Feb 21, 2019

Conversation

msya
Copy link
Contributor

@msya msya commented Feb 11, 2019

Summary

The errors are now propagated to the user with a single callback method.

authenticator.clientCredentials(object : VimeoCallback<BasicAccessToken> {

      override fun onSuccess(response: VimeoResponse.Success<BasicAccessToken>) {

      }

      override fun onError(error: VimeoResponse.Error) {

      }
})

The sealed class for error enumerates all type of errors that can happen:

sealed class VimeoResponse<out T> {

    data class Success<out T>(val data: T) : VimeoResponse<T>()

    sealed class Error(val message: String): VimeoResponse<Nothing>() {

        data class Api(val reason: ApiError): Error("API error")

        data class Exception(val throwable: Throwable): Error("Exception thrown")

        data class Parsing(val rawResponse: String): Error("Parsing error")

    }

}
  • ApiResponse was renamed to VimeoResponse.
  • VimeoCallbackAdapter was updated to use the Error sealed class above.

*
* @param reason Info on the error.
*/
data class Api(val reason: ApiError): Error("API error")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the Error message could have more information like

"API error: ${reason.errorCode ?: "unknown"}"

*
* @param rawResponse Raw response from the API.
*/
data class Parsing(val rawResponse: String): Error("Parsing error")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this error replaces the generic error - what is the logic behind any error that doesn't have a reason being a parsing error? What if a request is made for a missing resource and we get a 404? Will that be surfaced as a Parsing error, and, if so, is that really the "right" error?

Copy link
Contributor Author

@msya msya Feb 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A 404 error gives the following response from the API:

{
  "error": "The requested page could not be found"
}

If this error is successfully parsed, it will be surfaced to the client as an API error as follow:

ApiError(
    developerMessage=null, 
     errorMessage=The requested page could not be found, 
     errorCode=null, 
     invalidParameters=null, link=null
)

Suppose this error occurs and the error convert fails to convert it into a ApiError object, the client will be informed that a parsing error occurred. This will be the response to the client:

Parsing(
   rawResponse=Response{ protocol=http/1.1, code=404, message=Not Found, url=https://api.vimeo.com/oauth/authorize/clientttttt})

I could rename Parsing to Generic for a better name.

*
* @param message The error message.
*/
sealed class Error(val message: String): VimeoResponse<Nothing>() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

* @param exceptionFailure The exception thrown by Retrofit for the request.
*/
fun onExceptionError(exceptionFailure: ApiResponse.Failure.ExceptionFailure)
fun onError(error: VimeoResponse.Error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good for both Java and Kotlin consumers!

@msya
Copy link
Contributor Author

msya commented Feb 14, 2019

@anthonycr Back to you.

*
* @param rawResponse Raw response from the API.
*/
data class Generic(val rawResponse: String): Error("Generic error")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are certain APIs that require knowledge about the HTTP status code (e.g. 404, 401, 500) of an error. Such APIs include:

  • Adding a video to a channel, which performs a check to see if the video is in the channel and a 404 indicates that it is not in the channel.
  • Editing video settings, where a 404 indicates that the video was deleted.
  • Adding a comment to a video, where a 404 indicates that the video was deleted.
  • Playing a DRM protected video, where a 403 indicates that the device limit has been exceeded.

If we don't expose at least the error code here, it will be more difficult for consumers to use certain APIs. Of course in most cases, the specifics of the error are not important to the UI, but our consuming code often makes certain decisions based on that error code, so I would suggest adding the code in addition to the raw response.

@msya
Copy link
Contributor Author

msya commented Feb 21, 2019

@anthonycr Back to you.

Copy link
Contributor

@anthonycr anthonycr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@msya msya merged commit 5e30aaa into v2.0.0-auth Feb 21, 2019
@msya msya deleted the combine-error-callbacks branch February 21, 2019 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants