错误处理 redux-promise-middleware [英] Error handling redux-promise-middleware

查看:71
本文介绍了错误处理 redux-promise-middleware的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习 React 以及几乎所有围绕它的必要技术 - 所以我经常被我可能已经知道的事情绊倒.

I'm learning React, along with pretty much all the necessary technology around it all at once - so I often get tripped up by things I should probably know already.

我在处理异步事件时遇到了一个问题.我已经在网上搜索过,但没有什么能真正回答我正在寻找的内容.

I've encountered a problem when it comes to error handling my async events. I've scoured the web and nothing really answers exactly what I'm looking for.

我目前正在使用 redux 和 redux-promise-middleware 来处理异步操作,如下所示:

I'm currently using redux with redux-promise-middleware to handle the async actions, like this:

export function myFunc() {
  return {
    type: FETCH_FUNC,
    payload: new Promise((resolve, reject) => {
      fetch ('some/url/location/from/which/to/fetch')
        .then( response => {
          if (!response.ok){
            throw new Error(response);
            }
          resolve(response.json());
        }).catch(error => {
          reject(error);
        }),
    })
  };
}

这里有两件事:首先,代码在没有错误的情况下工作得很好.但是,当我故意在代码中创建错误时,正确的方法会被触发,但我仍然在控制台中出现以下错误:

There are two things here: first, the code works just fine when no errors are present. However, when I purposely create an error in the code the correct methods are firing but I still end up with the following error in my console:

Uncaught (in promise) Error: [object Response]

.catch(...) 块不应该处理这个吗?我错过了什么?我应该得到这个吗?如果是,为什么?

Should the .catch(...) block not be handling this? What am I missing? Should I be getting this anyway? If so, why?

其次,我读到将 fetch 包装在新的 Promise 中是一种反模式,并且几乎暗示这可能是导致问题的原因.我遇到的所有示例都以这种方式使用它.什么是替代方案?我如何在没有包装器的情况下触发解析/拒绝以调度下一个操作?

Secondly, I've read that wrapping the fetch inside a new Promise is an anti-pattern, and there was an almost-hint that this may be what's causing problems here. All the examples I've come across use it in this fashion. What's the alternative? How do I fire the resolve/reject to dispatch the next actions without the wrapper?

任何帮助将不胜感激.感谢网络大师.

Any help will be greatly appreciated. Thanks masters of the web.

从官方redux-promise-middleware github示例中,他们有以下代码:

From the official redux-promise-middleware github examples, they have the following code:

export default function request(url, options) {
  return new Promise((resolve, reject) => {
    if (!url) reject(new Error('URL parameter required'));
    if (!options) reject(new Error('Options parameter required'));

    fetch(url, options)
      .then(response => response.json())
      .then(response => {
        if (response.errors) reject(response.errors);
        else resolve(response);
      })
      .catch(reject);
  });
}

中间件的意图似乎是将 fetch 包装在 new Promise 中并捕获任何 reject .如果有人有使用 redux-promise-middleware 实现这一点的可行替代方法,或者可以详细说明为什么遵循这种模式,将不胜感激.

It seems to intention with the middleware is to wrap fetch inside a new Promise and catching any rejects. If anyone has a working alternative way of implementing this using redux-promise-middleware, or can elaborate on why its following this pattern that would be greatly appreciated.

不确定实现此目的的预期方式是什么,或者如何避免承诺中的 Uncaught 错误.除非您包含错误处理函数,否则简单地调用 Promise.reject(...) 会导致未捕获的错误:Promise.reject(...).then(() =>{...},错误 => {...}).在中间件中包含这个会导致被拒绝的动作永远不会被分派.我已经放弃了 redux-promise-middleware,直到找到合适的修复和/或实现.

Not sure what the intended way of implementing this is or how to avoid the Uncaught error in the promise. Simply calling Promise.reject(...) results in an uncaught error unless you include error handling functions: Promise.reject(...).then(() =>{...}, error => {...}). Including this with the middleware results in the rejected action never being dispatched. I've moved away from redux-promise-middleware till I can find a suitable fix and/or implementation.

推荐答案

我猜你得到的是预期的结果,这在中间件 文档:

I guess what you are getting is the expected result and this is mentioned clearly in the middleware documentation:

中间件分派被拒绝的动作,但不捕捉被拒绝的动作承诺.因此,您可能会在安慰.这是未捕获的被拒绝承诺的预期行为.发现错误是您的责任,而不是redux-promise-middleware 的责任.

The middleware dispatches rejected actions but does not catch rejected promises. As a result, you may get an "uncaught" warning in the console. This is expected behavior for an uncaught rejected promise. It is your responsibility to catch the errors and not the responsibility of redux-promise-middleware.

但是,如果您询问最佳实践,这就是我很久以前最终做的事情,并且与我完美配合:

But if you ask about best practices this is what i ended up doing from long time ago and it's working perfectly with me:

1- 对于某些承诺,您可以按照文档中的说明进行操作:

1- For some promises you can do as mentioned in the documentation:

dispatch({
    type: 'FOO_ACTION',
    payload: new Promise(() => {
      throw new Error('foo');
    })
  }).catch(error => {
    // catch and handle error or do nothing
  });

2- 要全局捕获所有被拒绝的承诺,请在 redux-promise-middleware 之前添加此中间件,如下所示:

2- To catch all rejected promises globally add this middleware before the redux-promise-middleware as follow:

/**
 * a utility to check if a value is a Promise or not
 * @param value
 */
const isPromise = value => value !== null && typeof value === 'object' && typeof value.then === 'function';


export default () => {

  const middleWares = [];

  // global error middleware
  middleWares.push(() => next => action => {

    // If not a promise, continue on
    if (!isPromise(action.payload)) {
      return next(action);
    }

    /**
     * include a property in `meta and evaluate that property to check if this error will be handled locally
     *
     * if (!action.meta.localError) {
     *   // handle error
     * }
     *
     * The error middleware serves to dispatch the initial pending promise to
     * the promise middleware, but adds a `catch`.
     */
    if (!action.meta || !action.meta.localError) {
      // Dispatch initial pending promise, but catch any errors
      return next(action).catch(error => {
        if (config.showErrors) { // here you can decide to show or hide errors
          console.log(`${action.type} unhandled rejection caught at middleware with reason: ${JSON.stringify(error.message)}.`);
        }
        return error;
      });
    }

    return next(action);
  });

  // middleware
  middleWares.push(thunk);
  middleWares.push(promise());  
  middleWares.push(logger());

  return applyMiddleware(...middleWares);
}

我想这正是你要找的 ;)

i guess this is exactly what you are looking for ;)

额外我强烈推荐 axios 过度获取,原因如下:

Extra I highly recommend axios over fetch for the following reasons:

  • 如果请求有错误代码,axios 模块会自动拒绝承诺,这是您需要在 fetch 中手动处理的内容
  • 在 axios 中,您可以使用默认的 base-url、header、interceptors ...
  • 创建实例
  • 在 axios 中,您可以使用令牌取消任何先前的请求,这对于自动完成和聊天应用程序非常有用
  • 还有 axios 在内部自动切换 xhrhttp 模块来执行基于环境(NodeJs 或浏览器)的 ajax 请求,我个人使用了相同的 redux 动作Electron、nodejs、浏览器和 react-native,一切正常
  • the axios module automatically reject the promise if the request has an error code which is something you need to keep manually handle in fetch
  • in axios you can create instance with default base-url,header,interceptors ...
  • in axios you can cancel any previous request using a token this is extremely useful specially for autocomplete and chat applications
  • also axios internally automatically switch between xhr and http modules to perform the ajax request based on the environment (NodeJs or Browser), i personally used the same redux actions in electron, nodejs, browser and react-native and it's all working fine

这篇关于错误处理 redux-promise-middleware的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆