Главная » Error » retrofit

retrofit

retrofit / retrofit / src / main / java / retrofit2 / Response.java / Jump to Code definitions Class Response Method success Method success Method success Method success Method error Method error Method raw Method code Method message Method хедерs Method isSuccessful Method body Method errorBody Method toString Code navigation index up-to-date

Go to file

  • TGo to file
  • Go to lineL
  • Go to definitionR
  • Copy path

  • Copy permalink

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.  Cannot retrieve contributors at this time

164 lines (147 sloc)

5.27 KB

Raw
Blame
Edit this fileE

Open in GitHub Desktop

  • Open with Desktop

  • View raw

  • Copy raw contents
    Copy raw contents
    Copy raw contents
    Copy raw contents
  • View blame

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
Show hidden characters

/*
* Copyright (C) 2015 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the “License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
packageretrofit2;
importjava.util.Objects;
importjavax.annotation.Nullable;
importokhttp3.Headers;
importokhttp3.Protocol;
importokhttp3.Request;
importokhttp3.ResponseBody;
/** An HTTP response. */
publicfinalclassResponse {
/** Create a synthetic successful response with {@code body} as the deserialized body. */
publicstatic Response success(@NullableTbody) {
returnsuccess(
body,
newokhttp3.Response.Builder() //
.code(200)
.message(“OK”)
.protocol(Protocol.HTTP_1_1)
.request(newRequest.Builder().url(“http://localhost/”).build())
.build());
}
/**
* Create a synthetic successful response with an HTTP status code of {@code code} and {@code
* body} as the deserialized body.
*/
publicstatic Response success(intcode, @NullableTbody) {
if (code < 200 || code >= 300) {
thrownewIllegalArgumentException(“code < 200 or >= 300: ” + code);
}
returnsuccess(
body,
newokhttp3.Response.Builder() //
.code(code)
.message(“Response.success()”)
.protocol(Protocol.HTTP_1_1)
.request(newRequest.Builder().url(“http://localhost/”).build())
.build());
}
/**
* Create a synthetic successful response using {@code хедерs} with {@code body} as the
* deserialized body.
*/
publicstatic Response success(@NullableTbody, Headersхедерs) {
Objects.requireNonNull(хедерs, “хедерs == null”);
returnsuccess(
body,
newokhttp3.Response.Builder() //
.code(200)
.message(“OK”)
.protocol(Protocol.HTTP_1_1)
.хедерs(хедерs)
.request(newRequest.Builder().url(“http://localhost/”).build())
.build());
}
/**
* Create a successful response from {@code rawResponse} with {@code body} as the deserialized
* body.
*/
publicstatic Response success(@NullableTbody, okhttp3.ResponserawResponse) {
Objects.requireNonNull(rawResponse, “rawResponse == null”);
if (!rawResponse.isSuccessful()) {
thrownewIllegalArgumentException(“rawResponse must be successful response”);
}
returnnewResponse<>(rawResponse, body, null);
}
/**
* Create a synthetic error response with an HTTP status code of {@code code} and {@code body} as
* the error body.
*/
publicstatic Response error(intcode, ResponseBodybody) {
Objects.requireNonNull(body, “body == null”);
if (code < 400) thrownewIllegalArgumentException("code < 400: " + code);
returnerror(
body,
newokhttp3.Response.Builder() //
.body(newOkHttpCall.NoContentResponseBody(body.contentType(), body.contentLength()))
.code(code)
.message(“Response.error()”)
.protocol(Protocol.HTTP_1_1)
.request(newRequest.Builder().url(“http://localhost/”).build())
.build());
}
/** Create an error response from {@code rawResponse} with {@code body} as the error body. */
publicstatic Response error(ResponseBodybody, okhttp3.ResponserawResponse) {
Objects.requireNonNull(body, “body == null”);
Objects.requireNonNull(rawResponse, “rawResponse == null”);
if (rawResponse.isSuccessful()) {
thrownewIllegalArgumentException(“rawResponse should not be successful response”);
}
returnnewResponse<>(rawResponse, null, body);
}
privatefinalokhttp3.ResponserawResponse;
privatefinal@NullableTbody;
privatefinal@NullableResponseBodyerrorBody;
privateResponse(
okhttp3.ResponserawResponse, @NullableTbody, @NullableResponseBodyerrorBody) {
this.rawResponse = rawResponse;
this.body = body;
this.errorBody = errorBody;
}
/** The raw response from the HTTP client. */
publicokhttp3.Responseraw() {
returnrawResponse;
}
/** HTTP status code. */
publicintcode() {
returnrawResponse.code();
}
/** HTTP status message or null if unknown. */
publicStringmessage() {
returnrawResponse.message();
}
/** HTTP хедерs. */
publicHeadersхедерs() {
returnrawResponse.хедерs();
}
/** Returns true if {@link #code()} is in the range [200..300). */
publicbooleanisSuccessful() {
returnrawResponse.isSuccessful();
}
/** The deserialized response body of a {@linkplain #isSuccessful() successful} response. */
public@NullableTbody() {
returnbody;
}
/** The raw response body of an {@linkplain #isSuccessful() unsuccessful} response. */
public@NullableResponseBodyerrorBody() {
returnerrorBody;
}
@Override
publicStringtoString() {
returnrawResponse.toString();
}
}
  • Copy lines
  • Copy permalink
  • View git blame
  • Reference in new issue

Go

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Get startedDalvin

Try и catch — обработка ошибок

При использовании любых сетевых запросов необходимо использовать обработку ошибок и исключительных ситуаций
try {…} catch(error){…}

<текстареа class="code">try {
var response = await http.get(‘https://json.flutter.su/echo’);
print(“Response status: ${response.statusCode}”);
print(“Response body: ${response.body}”);
} catch (error) {
print(error);
}

Данная конструкция позволит обработать ситуации когда нет доступа к сетевому ресурсу: выключена передача данных, отсутствует связь с сервером или указан неверный сетевой адрес.
В блоке try{…} выполняется код программы, если он не может быть выполнен — выполняется блок catch(error){…}.

Footer

© 2022 GitHub, Inc.

Parsing Error Response

The problem is how to parse the response if it’s not success. The idea is very simple. We need to create custom util for parsing the error. For example, we know that the server will return a JSON object with the following structure when an error occurs.

{
“success”: false,
“errors”: [
“Error message 1”,
“Error message 2”
] }

We need to create a util for parsing the error. It returns an Object containing parsed error body. First, we define the class which represents the parsed error.

APIError.java

public class APIError {
private boolean success;
private ArrayList messages;

public static class Builder {
public Builder() {}

public Builder success(final boolean success) {
this.success = success;
return this;
}

public Builder messages(final ArrayList messages) {
this.messages = messages;
return this;
}

public Builder defaultError() {
this.messages.add(“Something error”);
return this;
}

public APIError build() { return new APIError(this); }
}

private APIError(final Builder builder) {
success = builder.successs;
messages = builder.messages;
}
}

And here’s the util for parsing the response body. If you have different response body format, you can adjust it to suit your case.

ErrorUtils.java

public class ErrorUtils {
public static APIError parseError(final Response response) {
JSONObject bodyObj = null;
boolean success;
ArrayList messages = new ArrayList<>();

try {
String errorBody = response.errorBody().string();

if (errorBody != null) {
bodyObj = new JSONObject(errorBody);

success = bodyObj.getBoolean(“success”);
JSONArray errors = bodyObj.getJSONArray(“errors”);

for (int i = 0; i < errors.length(); i++) { messages.add(errors.get(i)); } } else { success = false; messages.add("Unable to parse error"); } } catch (Exception e) { e.printStackTrace();success = false; messages.add("Unable to parse error"); }return new APIError.Builder() .success(false) .messages(messages) .build(); } }

Finally, change the onResponse and onFailure methods. If response.isSuccessful() is false, we use the error parser. In addition, if the code go through onFailure which most likely we’re even unable to get the error response body, just return the default error.

Example.java

MyService myService = RetrofitClientInstance
.getRetrofitInstance()
.create(MyService.class);
Call<>> call = retailService.getItems();

call.enqueue(new Callback<>>() {
@Override
public void onResponse(final Call<>> call, final Response<>> response) {
if (response.isSuccessful()) {
List items = response.body();
Toast.makeText(getContext(), “Success”).show();
} else {
apiError = ErrorUtils.parseError(response);
Toast.makeText(getContext(), R.string.cashier_create_failed,
Toast.LENGTH_LONG).show();
}
}

@Override
public void onFailure(final Call call, final Throwable t) {
apiError = new APIError.Builder().defaultError().build();
Toast.makeText(getContext(), “failed”).show();
}
});

That’s how to parse error body in Retrofit 2. If you also need to define custom GSON converter factory, read this tutorial.

Share on FacebookShare on TwitterShare on TumblrShare by E-MailShare on PinterestShare on LinkedInShare on RedditShare on Hacker News

Types of Errors

errorTypeDescription
authorizationThe authorization failed.
expired_tokenThe OAuth token has expired.
insufficient_permissionsThe application has insufficient permissions to the resource.
insufficient_scopeThe application is missing a scope.
invalid_clientThe client_id provided is invalid.
invalid_grantThe grant_type value provided is invalid.
invalid_requestThe request syntax provided is invalid.
invalid_scopeThe scope provided is invalid.
invalid_tokenThe OAuth token provided is invalid.
not_foundThe resource with given id doesn’t exist.
oauthOAuth token is invalid, missing or expired.
requestThe API request failed.
systemThe system request failed.
unsupported_grant_typeThe grant_type provided is invalid.
unsupported_response_typeThe response_type provided is invalid.
validationRequest parameter is invalid or missing.

Headers — передача заголовков

Еще один параметр который может быть указан для всех методов — это заголовки хедерs (Map). В заголовках чаще всего передаются данные для авторизации и для выбора возвращаемых/передаваемых данных.

<текстареа class="code">var response = await http.post(‘https://json.flutter.su/echo’,
хедерs: {‘Accept’:’application/json’,’Authorization’:’Basic YWxhZGRpbjpvcGVuc2VzYW1l’}
);

OAuth2 Errors

Authorization Request Errors

According to the OAuth 2.0 RFC, if the redirect_uri is valid, the
user is redirected to the application’s redirect_uri, and any
errors are appended to the URI as a query string. However, this behavior could
be used in a phishing attack. Therefore, Fitbit’s OAuth 2.0 implementation
diverges from the spec in that the user will remain on
https://www.fitbit.com/oauth2/authorize
, and any errors will be displayed on the page.

All OAuth2 errors, excluding the Authorization Request Errors, will be
suffixed with:

“Visit https://dev.fitbit.com/reference/web-api/oauth2 for more information
on the Fitbit Web API authorization process.”

Like so:

{“errors”:[{“errorType”:”invalid_request”,”message”:”Missing parameters: refresh_token. Visit https://dev.fitbit.com/reference/web-api/oauth2 for more information on the Fitbit Web API authorization process.”}],”success”:false}

Access Token Request Errors

401 Unauthorized errors will occur when the “Authorization” хедер is invalid
or missing. In addition to an “errors” JSON object, the API will respond with
a WWW-Authenticate хедер and value of
Basic realm=”api.fitbit.com”. However, if the API cannot
determine the authentication scheme due to the Authorization хедер missing or
the word “Basic” being misspelled, the WWW-Authenticate хедер
will return the value Bearer realm=”api.fitbit.com”.

Refresh Token Request Errors

For 401 Unauthorized errors that occur during a refresh token request, the API
will respond with a WWW-Authenticate хедер and a value of
Bearer realm=”api.fitbit.com”, rather than a value of Basic
realm=”[redirect_uri]”.
On rare occasions, the application may encounter a 409 Conflict error for
concurrent refresh token requests. The avoid this error, applications should
avoid making multiple, concurrent refresh token requests. Verify the refresh
token process was not started for the same token more than once, and, where
applicable, coordinate refresh token requests across processes.

POST запросы к серверу

В post запросах можно передавать данные в теле запроса с помощью параметра body и кодировку encoding если она отличается от utf-8 (по умолчанию), синхронное выполнение метода с помощью await:

<текстареа class="code">var response = await http.post(‘https://json.flutter.su/echo’, body: {‘name’:’test’,’num’:’10’});
print(“Response status: ${response.statusCode}”);
print(“Response body: ${response.body}”);В параметре body вы можете передать: [String], [List], [Map].

Источники

  • https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit2/Response.java
  • https://medium.com/@Dalvin/how-to-parse-http-error-body-using-retrofit-bb348f67fc54
  • https://flutter.su/tutorial/7-HTTP-network-requests
  • https://www.woolha.com/tutorials/android-retrofit-2-custom-error-response-handling
  • https://dev.fitbit.com/build/reference/web-api/troubleshooting-guide/error-handling/
[свернуть]
Решите Вашу проблему!


×
Adblock
detector