I have been looking around the web, offical Android Dev. website, Medium, in this repository Issue category and in the Source code.
I am working with the ExoPlayer error handling. I found that when my Server response is an exception of type "InvalidResponseCodeException" I am not able to find the server message, just the default http status message (in the LoadErrorHandlingPolicy custom class as well as for the player listener onPlayerError() method). I am wondering if is there a way to get it or it is a feature not yet implemented.
It should be available through InvalidResponseCodeException#responseMessage. Is that empty? If so, are you sure the server is providing a non-empty response body? Have you tried different HTTP DataSources?
It should be available through InvalidResponseCodeException#responseMessage. Is that empty? If so, are you sure the server is providing a non-empty response body? Have you tried different HTTP DataSources?
InvalidResponseCodeException#responseMessage prints the default http status message such as 401 Unauthorized, not the server message (eg. For 401: You are not authorized)...
Oh right, the responseMessage doesn't contain the response body. I can confirm this is not provided out of the box. I don't think reading the response body for an error is something we want to add to any default implementation.
Can you explain the usecase for this?
Oh right, the responseMessage doesn't contain the response body. I can confirm this is not provided out of the box. I don't think reading the response body for an error is something we want to add to any default implementation.
Can you explain the usecase for this?
It is usefull because we don't want to keep this messages inside the app, these are messages that may change over time and mostly they are translated.
For example we are handling error 429 "Too many requests", when ExoPlayer reaches this error it will show an AlertDialog with the wanted information.
We want to have this message customizable on the Server side.
I hope it is a little bit more clear.
The easiest way I can think of implementing the provision of the error's response body is including it in the InvalidResponseCodeException. However, it's probably not ideal to block until we read the response body, before we throw the exception. So, we might also want to add a per-implementation flag that enables populating the response body for this case.
@JonathanImperato, I see slim chances of us adding this any time soon. You might want to think of using your own DataSource implementation that does this for you. It shouldn't be hard, if you part from an existing implementation.
@ojw28, can you think of a better way of providing the response body of a non-2xx response?
Not ideal, but if you can have the server return the error in a header, you can get the error message that way. I have a custom header called X-Client-Error, which I am able to access.
@Override
public void onPlayerError(ExoPlaybackException error) {
String message = "Unknown";
switch (error.type) {
case ExoPlaybackException.TYPE_SOURCE:
message = "TYPE_SOURCE: " + error.getSourceException().getMessage();
if (error.getSourceException() instanceof HttpDataSource.InvalidResponseCodeException) {
HttpDataSource.InvalidResponseCodeException invalidResponseCodeException = (HttpDataSource.InvalidResponseCodeException) error.getSourceException();
List<String> strings = invalidResponseCodeException.headerFields.get("X-Client-Error");
if (strings.size() > 0) {
message += "\n" + strings.get(0);
}
}
break;
...
Not ideal, but if you can have the server return the error in a header, you can get the error message that way. I have a custom header called
X-Client-Error, which I am able to access.@Override public void onPlayerError(ExoPlaybackException error) { String message = "Unknown"; switch (error.type) { case ExoPlaybackException.TYPE_SOURCE: message = "TYPE_SOURCE: " + error.getSourceException().getMessage(); if (error.getSourceException() instanceof HttpDataSource.InvalidResponseCodeException) { HttpDataSource.InvalidResponseCodeException invalidResponseCodeException = (HttpDataSource.InvalidResponseCodeException) error.getSourceException(); List<String> strings = invalidResponseCodeException.headerFields.get("X-Client-Error"); if (strings.size() > 0) { message += "\n" + strings.get(0); } } break; ...
Yes, it is what I am doing right now, but instead of a string I pass a serialized json.
Pretty much all apps that I've seen will include the strings (and translations) as resources inside the app. I don't understand why it would be particularly important to enable these messages to be changed on the server side. Typically an error code has a well defined meaning, and the strings inside the app will reflect that. I understand that the exact wording may be tweaked from release to release, but I'd expect any string that was included in a previous release to still make sense. I also don't understand why translation is important here. Android already provides a resources mechanism that supports translations.
I don't think it's important that we go out of our way to support this use case. Putting content into a response header as described above is one way of achieving what's being requested, for those who really want to do this.