Retrofit: VoidResponseBodyConverter return null

Created on 8 Dec 2017  路  2Comments  路  Source: square/retrofit

Bug report
my interface Returntype is Observable
Observable getHealthCardTypeDict1();

getHealthCardTypeDict1()
                .map(new Function<Void, Void>() {
                    @Override
                    public Void apply(@NonNull Void aVoid) throws Exception {
                        return aVoid;
                    }
                })
                .subscribe(new Observer<Void>() {

                    @Override
                    public void onError(Throwable e) {
                        System.out.println("----------------getHealthCardTypeDict1" + e.getMessage());
                    }

                    @Override
                    public void onComplete() {

                    }

                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(Void ss) {
                        System.out.println("----------------getHealthCardTypeDict1");
                    }
                });

onError was called
Rxjava2 cannot support null Value

java.lang.NullPointerException: The mapper function returned a null value.

I found reason is VoidResponseBodyConverter return null value
is should be like this

public class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
    static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
    public static Void DEFAULT_VOID_INSTIANCE;
    @Override
    public Void convert(ResponseBody value) throws IOException {
        value.close();
        if (DEFAULT_VOID_INSTIANCE == null) {
            Constructor<?>[] cons = Void.class.getDeclaredConstructors();
            cons[0].setAccessible(true);
            try {
                DEFAULT_VOID_INSTIANCE = (Void) cons[0].newInstance(new Object[]{});
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return DEFAULT_VOID_INSTIANCE;
    }
}

Most helpful comment

This isn't linked to how Retrofit works. See the RxJava wiki on "What's different in 2.0":

[...] Observable<Void> can no longer emit any values but only terminate normally or with an exception. API designers may instead choose to define Observable<Object> with no guarantee on what Object will be (which should be irrelevant anyway).

Void is not instantiable. Your converter basically returns null which RxJava2 doesn't allow.

All 2 comments

This isn't linked to how Retrofit works. See the RxJava wiki on "What's different in 2.0":

[...] Observable<Void> can no longer emit any values but only terminate normally or with an exception. API designers may instead choose to define Observable<Object> with no guarantee on what Object will be (which should be irrelevant anyway).

Void is not instantiable. Your converter basically returns null which RxJava2 doesn't allow.

i understand 锛宼hank you

Was this page helpful?
0 / 5 - 0 ratings