retrofit 관련 에러처리 질문

조회수 1956회

안녕하세요 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(); 도 해줬으나 흠.. 동일하게 뜨네요. 제가 놓치고 잇는것이 있는것 같은데 고수분들 조언 부탁드립니다 ㅎㅎ

  • (•́ ✖ •̀)
    알 수 없는 사용자

3 답변

  • 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문으로 예외처리를 하거나 예외가 발생하는 근본적인 부분을 (개선할 수 있다면) 수정하는 방향으로 코드를 변경하는게 좋을 것 같습니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 아아 내부적으로 그렇게 돌아가는중이군요 ~ 흠 예외처리한다고하는데 혹시나놓첬을때 저렇게뜰까봐그랫는데 더꼼꼼하게하는수밖에없군요 ㅎㅎ 답변감사합니다~ 알 수 없는 사용자 2016.5.16 16:53
  • 에러가 makeData에서 발생하고 있는지 onNext()에서 발생하는건지 에러로그가 없어서 잘은 모르겠지만 makeData()에서 UI 작업을 하신다고 하셨는데 UI 작업은 항상 Main thread에서 처리를 하셔야 합니다. ui 작업을 메인스레드에서 작업하신게 맞는지 확인해보세요.

    runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // UI 작업
                    }
                });
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 에러나는걸 잡는게 질문이아니였어서요 ㅎㅎ 관심감사합니다~~ 알 수 없는 사용자 2016.5.16 16:54
  • 다음과 같이 해주셔야 네트워크 에러인 경우에만 팝업이 뜹니다.

    @Override
    public void onError(Throwable e) {
        if (e instanceOf IOException)
            showNetworkPopup();
        e.printStackTrace();
    }
    
    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)