简体   繁体   English

retrofit2 rxjava2全局处理网络异常和自动身份验证

[英]retrofit2 rxjava2 handling network exceptions globally and auto authentification

I have next code for handling errors. 我有用于处理错误的下一个代码。 This code works perfect for handling errors, but i want to handle "not authorized" error. 这段代码非常适合处理错误,但是我想处理“未经授权”的错误。

public class RxErrorHandlingCallAdapterFactory extends CallAdapter.Factory {

    private RxJava2CallAdapterFactory rxJavaCallAdapterFactory;
    private Context context;
    private Gson gson;

    public RxErrorHandlingCallAdapterFactory(Context context, Gson gson) {
        this.context = context;
        this.gson = gson;
        rxJavaCallAdapterFactory = RxJava2CallAdapterFactory.create();
    }

    public static CallAdapter.Factory create(Context context, Gson gson) {
        return new RxErrorHandlingCallAdapterFactory(context, gson);
    }

    @Nullable
    @Override
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        return new RxCallAdapterWrapper<>(retrofit, rxJavaCallAdapterFactory.get(returnType, annotations, retrofit));
    }

    private class RxCallAdapterWrapper<R> implements CallAdapter<R, Observable<R>> {

        private final Retrofit retrofit;
        private final CallAdapter<R, ?> wrappedCallAdapter;

        public RxCallAdapterWrapper(Retrofit mRetrofit, CallAdapter<R, ?> wrapped) {
            this.retrofit = mRetrofit;
            this.wrappedCallAdapter = wrapped;
        }

        @Override
        public Type responseType() {
            return wrappedCallAdapter.responseType();
        }

        @SuppressWarnings("unchecked")
        @Override
        public Observable<R> adapt(@NonNull Call<R> call) {
            return ((Observable<R>) wrappedCallAdapter.adapt(call))
                    .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends R>>() {
                @Override
                public ObservableSource<? extends R> apply(Throwable throwable) throws Exception {
                    return Observable.error(convertError(throwable));
                }
            });
        }

        private ErrorThrowable convertError(final Throwable throwable) {
            Error error = new Error(Error.ErrorCodes.UNKNOWN_ERROR, context.getString(com.inscreen.R.string.unknown_error));

            if (throwable instanceof ConnectException) {
                error = new Error(Error.ErrorCodes.SOCKET_TIMEOUT_EXCEPTION,
                        context.getString(com.inscreen.R.string.error_connection));
                return new ErrorThrowable(throwable, error);
            }

            if (throwable instanceof SocketTimeoutException) {
                error = new Error(Error.ErrorCodes.SOCKET_TIMEOUT_EXCEPTION,
                        context.getString(com.inscreen.R.string.error_socket_timeout));
                return new ErrorThrowable(throwable, error);
            }
            if (throwable instanceof HttpException) {
                HttpException exception = (HttpException) throwable;
                Response response = exception.response();
                if (response != null && !response.isSuccessful()) {
                    ResponseBody errorBody = response.errorBody();
                    if (errorBody != null) {
                        try {
                            error = gson.fromJson(errorBody.string(), Error.class);
                        } catch (JsonSyntaxException | IOException exc) {
                            return new ErrorThrowable(throwable, error);
                        }
                    }
                }
            }

            return new ErrorThrowable(throwable, error);
        }
    }

}

When error code "not authorised" I want to automatically log in. Something like this https://stackoverflow.com/a/26201962/6805851 but i don't know how to do it. 错误代码为“未授权”时,我要自动登录。类似https://stackoverflow.com/a/26201962/6805851的内容,但我不知道该怎么做。

@SuppressWarnings("unchecked")
        @Override
        public Observable<R> adapt(@NonNull Call<R> call) {
            return ((Observable<R>) wrappedCallAdapter.adapt(call))
                    .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends R>>() {
                @Override
                public ObservableSource<? extends R> apply(Throwable throwable) throws Exception {
                    if (errorrCodeNotAuthorized) {
                        return "AutorizationObservable".flatMap(return "OLD REQUEST OBSERVABLE");
                    } else {
                        return Observable.error(convertError(throwable));
                    }
                }
            });
        }

How could i return "OLD REQUEST OBSERVABLE" in flatMap or how to start old request after log in ? 如何在flatMap中返回“ OLD REQUEST OBSERVABLE”或登录后如何启动旧请求?

I found a solution. 我找到了解决方案。

if (error.isNotAuthorized()) {
                                        UserManager userManager = Application.getAppComponent().getUserManager();
                                        String email = userManager.getEmail();
                                        String password = userManager.getPassword();
                                        return userManager.getLoginObservable(email, password)
                                                .flatMap(new Function<User, ObservableSource<R>>() {
                                                    @Override
                                                    public ObservableSource<R> apply(User user) throws Exception {
                                                        return ((Observable<R>) wrappedCallAdapter.adapt(call));
                                                    }
                                                });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM