[NGXS] Composition과 Error Handling

CheolHyeon Park·2021년 8월 2일
0

Angular

목록 보기
7/7

Composition

상속개념을 이용하여, 여러 store들을 구성할 수 있다.

@State({
	name: 'zoo',
	defaults: {
		type: null
	}
})
@Injectable()
class ZooState {
	@Action(Eat)
	eat(ctx: StateContext) {
		ctx.setState({ type: 'eat' });
	}
}

@State({
	name: 'stlzoo'
})
@Injectable()
class stLouisZooState extends ZooState {
	@Action(Drink)
	drink(ctx: StateContext) {
		ctx.setState({ type: 'drink' });
	}
}

Error Handling

NGXS에서는 액션이 에러를 던진다면, Angular의 기본 ErrorHandler 를 사용한다. ErrorHandler를 오버라이드하여 사용한다.

import { NgModule, ErrorHandler} from '@angular/core';

@Injectable()
export class MyErrorHandler extends ErrorHandler {
	handleError(error: any) {
		console.log('Error! : ', error);
		throw error;
	}
}

@NgModule({
	imports: [AppComponent],
	providers: [
		{
			provide: ErrorHandler,
			useClass: MyErrorHandler
		}
	]
})
export class AppModule {}

Handling errors within an @Select

@Component({ ... })
class AppComponent {
  @Select(state => state.count.number.value) count$: Observable<number>;
}
this.store.reset({}); // reset all states

위와 같은 상황에서

RxJS에서 에러가 throw되면 자동적으로 stream이 complete된다.

suppressErrors 옵션을 false로 바꾸어 에러 suppressing을 하지 못하도록 해야한다.

@NgModule({
  imports: [
    NgxsModule.forRoot([CountState], {
      selectorOptions: {
        suppressErrors: false // `true` by default
      }
    })
  ]
})
export class AppModule {}

위의 옵션은 에러를 track할 수 있게 해주고, 그것을 처리할 수 있게 해준다.

@Component({ ... })
class AppComponent {
  @Select(state => {
    try {
      return state.count.number.value;
    } catch (error) {
      console.log('error', error);
      // throw error;
      // Automatic unsubscription will occur if you use the `throw` statement here. Skip it if you don't want the stream to be completed on error.
    }
  })
  count$: Observable<number>;
}

Handling errors within @Action

액션안에서 에러를 처리할 수 있다. 그런경우, 이 에러는 global ErrorHandler나 dispatch Observable까지 전파되지 못한다.

Handling errors after dispatching an Action

만약 처리되지 않은 예외가 액션에서 던져진다면, 그 에러는 ErrorHandler에 전파될 것이다. 그리고 그것을 dispatch를 subscribe하고 있는 옵져버블에서 catch할 수 있다.

만약 dispatch 옵저버블을 구독하고 있다면 두번 캐치할 수 있다.(ErrorHandler 와 dispatch)

@Action(UnhandledError)
  unhandledError(ctx: StateContext<StateModel>) {
    // error is thrown
  }
unhandled() {
    this.store.dispatch(new UnhandledError()).pipe(
      catchError(err => {
        console.log('unhandled error on dispatch subscription')
        return of('')
      })
    ).subscribe();
  }

@Action안에서 에러를 핸들링하도록 추천하고, 에러를 반영한 상태를 업데이트하라.

출처
NGXS - 공식문서(Composition)
NGXS - 공식문서(Error Handling)

profile
나무아래에 앉아, 코딩하는 개발자가 되고 싶은 박철현 블로그입니다.

0개의 댓글