hyrulelink16 hyrulelink16 - 1 month ago 24
Android Question

RXJava: mapping fatal exception

I'm downloading JSON array and mapping it into POJO using retrofit. I've successfully downloaded it but I have problem mapping it from API do domain object with rxJava.

This is my presenter:

public class WeatherPresenterImpl extends BasePresenter implements WeatherPresenter {

private final NetworkStateUtil networkStateUtil;
private WeakReference<WeatherListView> viewWeakReference;
private final WeatherApi weatherApi ;
private final WeatherDataMapper weatherDataMapper;
private final Scheduler observeScheduler;
private final Scheduler subscribeScheduler;

public WeatherPresenterImpl(final NetworkStateUtil networkStateUtil, final WeatherApi weatherApi, final
WeatherDataMapper weatherDataMapper, final Scheduler subscribeScheduler, final Scheduler observeScheduler) {
this.networkStateUtil = networkStateUtil;
this.weatherApi = weatherApi;
this.weatherDataMapper = weatherDataMapper;
this.observeScheduler = observeScheduler;
this.subscribeScheduler = subscribeScheduler;
}

@Override
public void activate(final WeatherListView viewWeakReference) {
this.viewWeakReference = new WeakReference<>(viewWeakReference);
}

@Override
public void requestWeatherData(String city, String apiKey) {
if (networkStateUtil.isConnected()) {

addSubscription(weatherApi.getWeather(city, WeatherApi.APIKEY)
.map(weatherDataMapper::map)
.subscribeOn(subscribeScheduler)
.observeOn(observeScheduler)
.subscribe(this::onRequestCityDataOnNext, this::onRequestCityDataError));
} else {
ifViewNotNull(WeatherListView::showNoConnectionMessage);
getDataFromDatabase();
}
}

@Override
public void requestWeatherData() {
Log.e("success","success");
}

private void onRequestCityDataError(final Throwable throwable) {
Log.e("fail",throwable.getMessage());

}

private void onRequestCityDataOnNext(final List<WeatherData> weatherDatas) {

ifViewNotNull((weatherListView) -> {
weatherListView.setWeatherData(weatherDatas);
});

}

private void ifViewNotNull(final Action1<WeatherListView> func) {
final WeatherListView weatherListView = viewWeakReference.get();
if (weatherListView != null) {
func.call(weatherListView);
}
}


this is my Mapper class:

public final class WeatherDataMapper {

public final List<WeatherData> map(final WeatherDataApi listWeatherDataApi) {

List<WeatherData> weatherDataModelList = Collections.emptyList();

final int numberOfDays = 3;

for (int i = 0; i < numberOfDays; i++) {
String tempMin = String.valueOf(KelvinConverterUtil.convertKelvinToCelsius(listWeatherDataApi.list.get(i).temp.min));
String tempMax = String.valueOf(KelvinConverterUtil.convertKelvinToCelsius(listWeatherDataApi.list.get(i).temp.max));
String cityName = listWeatherDataApi.city.name;
String description = listWeatherDataApi.list.get(i).weather.get(0).description;
String humidity = String.valueOf(listWeatherDataApi.list.get(i).humidity);
String pressure = String.valueOf(listWeatherDataApi.list.get(i).pressure);
String icon = String.valueOf(listWeatherDataApi.list.get(i).weather.get(0).icon);
weatherDataModelList.add(i, new WeatherData(tempMin, tempMax, cityName, description, humidity, pressure, icon));
}
return weatherDataModelList;
}
}


And this is the Exception that I get when I run it:

10-18 17:42:48.700 14461- 14606/package.com.openweatherappE/AndroidRuntime:FATAL EXCEPTION: RxIoScheduler-2
Process: package.com.openweatherapp, PID: 14461
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:192)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:276)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:219)
at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:220)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: rx.exceptions.CompositeException: 2 exceptions occurred.
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:192) 
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120) 
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:276) 
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:219) 
at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:220) 
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received =>
at android.util.Log.getStackTraceString(Log.java:338)
at com.android.internal.os.RuntimeInit.Clog_e(RuntimeInit.java:61)
at com.android.internal.os.RuntimeInit.-wrap0(RuntimeInit.java)
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:86)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:66)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:404)
at package.com.openweatherapp.model.WeatherDataMapper.map(WeatherDataMapper.java:27)
at package.com.openweatherapp.presenter.WeatherPresenterImpl$$Lambda$1.call(Unknown Source)
at rx.internal.operators.OperatorMap$MapSubscriber.onNext(OperatorMap.java:66)
at retrofit.RxSupport$2.run(RxSupport.java:56)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818) 
Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: package.com.openweatherapp.data.pojo.WeatherDataApi.class
at rx.internal.operators.OperatorMap$MapSubscriber.onNext(OperatorMap.java:70)
at retrofit.RxSupport$2.run(RxSupport.java:56) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at retrofit.Platform$Android$2$1.run(Platform.java:142) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.e(Log.java:232)
at package.com.openweatherapp.presenter.WeatherPresenterImpl.onRequestCityDataError(WeatherPresenterImpl.java:61)
at package.com.openweatherapp.presenter.WeatherPresenterImpl.access$lambda$1(WeatherPresenterImpl.java:0)
at package.com.openweatherapp.presenter.WeatherPresenterImpl$$Lambda$3.call(Unknown Source)
at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:276)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:219)
at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:220)
at rx.in
10-18 17:42:48.744 14461-14610/package.com.openweatherapp I/Process: Sending signal. PID: 14461 SIG: 9

Answer
List<WeatherData> weatherDataModelList = Collections.emptyList();

The resulting collection is immutable, hence you're getting an UnsupportedOperationException. On top of that, you get a Caused by: java.lang.NullPointerException: println needs a message because in your onRequestCityDataError you fail to handle exceptions that don't have a message.

Comments