retrofit 관련 에러처리 질문


안녕하세요 retrofit + rxandroid 로 프로젝트 진행준인데요 질문사항이 있어서 문의드립니다. ㅎㅎ


 NetworkService service = NetworkManager.getInstance(mContext).getService();
 Observable<StudyPlanGraphResData> resDataObservable = service.getStudyPlanUser(mUserStudyPlanInfo.getMbrNo(), subjectCd);
        resDataObservable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<StudyPlanGraphResData>() {
            @Override
            public void onCompleted() {


            }

            @Override
            public void onError(Throwable e) {
                showNetworkPopup();
                e.printStackTrace();
            }

            @Override
            public void onNext(StudyPlanGraphResData studyPlanGraphResData) {
                studyPlanGraphResData.setResult();

                KumonLoadingPopup.getInstance(mContext).dismissLoading();
                if (studyPlanGraphResData.isSucess()) {

                    makeData();


                } else {
                    CommonPopup errorPopup = new CommonPopup(mContext, ONEBUTTON);
                    errorPopup.setPopupText(studyPlanGraphResData.getResultMsg());
                    errorPopup.DialogShow();

                }
            }
        });
//서버 통신 후 데이터 작업 및 UI 작업
public void makeData(){
    이부분에서 에러 발생 
}

현재 위와 같이 통신을 진행 하였는데요. 통신 성공 후 onNext 에서 데이터 가공후 UI작업을하다가 makeData() 라는 메소드에서 에러가 나게되면 통신 onError 로 타서 에러팝업이 뜨게 됩니다. 해결하기위해 makeData() 전에 this.unsubscribe(); 도 해줬으나 흠.. 동일하게 뜨네요. 제가 놓치고 잇는것이 있는것 같은데 고수분들 조언 부탁드립니다 ㅎㅎ


조회수 328


3 답변


좋아요
2
싫어요
채택취소하기

makeData()에서 에러 발생 시 Subscriber의 onError()가 호출되는 이유는 rxJava의 SafeSubscriber.java, Exceptions.java 코드에서 확인할 수 있습니다.

SafeSubscriber.java

@Override
public void onNext(T args) {
    try {
        if (!done) {
            actual.onNext(args);
        }
    } catch (Throwable e) {
        // we handle here instead of another method so we don't add stacks to the frame
        // which can prevent it from being able to handle StackOverflow
        Exceptions.throwOrReport(e, this);
    }
}

Exceptions.java

public static void throwOrReport(Throwable t, Observer<?> o) {
    Exceptions.throwIfFatal(t);
    o.onError(t);
}

위 코드에서 actual.onNext(args)가 try-catch으로 감싸져있기 때문에 makeData()에서 에러가 발생하면 Exceptions.throwOrReport()를 호출하고 함수 내부에서 Subscriber의 onError()를 호출하기 때문입니다. 따라서 unsubscribe() 호출 여부와는 상관없이 onNext()에서 예외가 발생하면 onError()가 호출됩니다.

해결하고자 하는 것이 makeData()에서 에러 발생 시 onError()가 호출되지 않도록 하는 것이라면 makeData() 내부에서 try-catch문으로 예외처리를 하거나 예외가 발생하는 근본적인 부분을 (개선할 수 있다면) 수정하는 방향으로 코드를 변경하는게 좋을 것 같습니다.


  • 아아 내부적으로 그렇게 돌아가는중이군요 ~ 흠 예외처리한다고하는데 혹시나놓첬을때 저렇게뜰까봐그랫는데 더꼼꼼하게하는수밖에없군요 ㅎㅎ 답변감사합니다~    dunkindonass   2016.5.16 16:53     

에러가 makeData에서 발생하고 있는지 onNext()에서 발생하는건지 에러로그가 없어서 잘은 모르겠지만 makeData()에서 UI 작업을 하신다고 하셨는데 UI 작업은 항상 Main thread에서 처리를 하셔야 합니다. ui 작업을 메인스레드에서 작업하신게 맞는지 확인해보세요.

runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // UI 작업
                }
            });
  • 2016년 05월 16일에 작성됨
    안드로이드, 루비온레일즈

  • 에러나는걸 잡는게 질문이아니였어서요 ㅎㅎ 관심감사합니다~~    dunkindonass   2016.5.16 16:54     

다음과 같이 해주셔야 네트워크 에러인 경우에만 팝업이 뜹니다.

@Override
public void onError(Throwable e) {
    if (e instanceOf IOException)
        showNetworkPopup();
    e.printStackTrace();
}
  • 2016년 06월 21일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close