首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有可能在不完成可见流的情况下在ngrx-effects中抛出错误?

是否有可能在不完成可见流的情况下在ngrx-effects中抛出错误?
EN

Stack Overflow用户
提问于 2017-12-20 06:32:49
回答 2查看 2.8K关注 0票数 2

有没有办法在ngrx-effects流中使用throw来处理错误对象,而不需要完成流?

我已经读到了这些关于为什么流被抛出错误而被杀死的答案:

@ngrx Effect does not run the second time

ngrx effects error handling

https://github.com/ngrx/platform/issues/646

我的问题是,如果我实现了Angular ErrorHandler来捕获错误,我是否能够将其与ngrx效果一起使用。

代码语言:javascript
复制
@Effect()
  loginUserEffect: Observable<loginActions.Actions> = this.actions$
    .ofType(loginActions.LOGIN_USER)
    .map((action: loginActions.LoginUser) => action.payload)
    .mergeMap(payload => {
      return this.loginService
        .authenticate(payload)
        .map(response => new loginActions.LoginUserSuccess(response))
        .catch((error: HttpErrorResponse) =>
          of(new loginActions.LoginUserFailure(error))
        )
  })

  @Effect({ dispatch: false })
  loginUserEffectSuccess$ = this.actions$
    .ofType(loginActions.LOGIN_USER_SUCCESS)
    .do(() => this.router.navigate(['/account-home']))

  @Effect({ dispatch: false })
  loginUserEffectFailure$ = this.actions$
    .ofType(loginActions.LOGIN_USER_FAILURE)
    .map((action: loginActions.LoginUserFailure) => {
      throw action.payload // Stream completes
  })

我想我可以创建一些方法来处理错误,而不涉及抛出任何东西,但希望确保我需要走这条路,或者是否有一种方法可以让它们和平共存。

目前在我实现ErrorHander的类中,我有以下代码:

代码语言:javascript
复制
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
  private messagesService: MessagesService
  private router: Router

  constructor(
    private injector: Injector, // DI workaround (https://stackoverflow.com/a/41585902)
    private errorLoggerService: ErrorLoggerService
  ) {
    // DI workaround (https://stackoverflow.com/a/41585902)
    setTimeout(() => (this.messagesService = injector.get(MessagesService)))
    setTimeout(() => (this.router = injector.get(Router)))
  }

  handleError(error) {
    if (error instanceof HttpErrorResponse) {
      this.handleServerError(error)
    } else if (error instanceof ClientError) {
      this.handleClientError(error)
    } else {
      this.handleUnexpectedError(error)
    }
  }

这意味着我只是抛出错误,并根据类型来处理它们

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-03 09:57:42

如果您希望抛出一个无法被可观察对象捕获的错误,而是将其报告给全局错误处理程序,则需要从可观察对象的调用堆栈外部抛出该错误。

你可以这样做:

代码语言:javascript
复制
@Effect({ dispatch: false })
loginUserEffectFailure$ = this.actions$
  .ofType(loginActions.LOGIN_USER_FAILURE)
  .do(action => setTimeout(() => { throw action.payload; }, 0))
})

但是,由于您的效果位于已经使用Angular的DI机制的类中,因此我建议您改为注入GlobalErrorHandler并直接调用它。

如果没有setTimeout调用,我想测试起来也会更清晰、更容易。

票数 2
EN

Stack Overflow用户

发布于 2018-01-11 12:14:25

我最终创建了一个错误操作:

代码语言:javascript
复制
@Effect()
  loginUserEffectFailure$: Observable<
    errorsActions.Actions
  > = this.actions$
    .ofType(loginActions.LOGIN_USER_FAILURE)
    .map(
      (action: loginActions.LoginUserFailure) =>
        new errorsActions.Error(action.payload)
    )

并使其以专用效果调用错误处理程序:

代码语言:javascript
复制
@Effect({ dispatch: false })
  errorEffect$ = this.actions$
    .ofType(errorsActions.ERROR)
    .map((action: errorsActions.Error) =>
      this.clientErrorHandler.handleError(action.payload)
    )

我离开了全局错误处理程序,以便捕获和记录意外的异常。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47896171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档