使用Vuex和Axios进行Vuejs错误处理的最佳实践

时间:2018-02-07 06:03:44

标签: vue.js axios vuex

我正在使用Vuex + axios,我想知道处理vuex + axios错误的最佳做法。我现在正在做的是,当我请求使用axios并且它返回错误时,它将在变异中提交并更新我的状态。我想要做的是,如果我的请求出现响应错误,它将返回到我的组件,以便我可以更快地处理错误。

与angular相似,有一个依赖注入,响应将返回到组件。

9 个答案:

答案 0 :(得分:12)

吃蛋糕也吃。假设您已经在使用interceptor ...

axios.interceptors.response.use(function (response) {
  return response;
}, function (error) {
  store.commit('ERROR', error) // just taking some guesses here
  return Promise.reject(error) // this is the important part
})

这会使承诺拒绝回到调用者,所以在你的组件中,就像......

axois.whatever(...).then(res => {
  // happy days
}, err => {
  // oh noes!
})

答案 1 :(得分:5)

让我告诉你我用于错误记录的方法就是这个。 通过此代码,您可以通过代码处理所有vue错误。

window.onerror = function (message, source, lineno, colno, error) {
  /// what you want to do with error here
};

这是浏览器的全局错误处理程序。如果有任何错误未被捕获,可由此处理。

此外,如果你想处理你的错误。你可以这样做。

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
      // when you throw error this will also fetch error.
       throw error;
  });

如果你想查看错误处理的vue,你可以去。    https://vuejs.org/v2/api/#errorHandler

Vue.config.errorHandler = function (err, vm, info) {
  // handle error
  // `info` is a Vue-specific error info, e.g. which lifecycle hook
  // the error was found in. Only available in 2.2.0+
}

让我给你一个使用window.onerror的链接

https://github.com/stacktracejs/stacktrace.js/

答案 2 :(得分:2)

我只是用渔获物。在切换到vuex之前,我一直在使用相同的东西。它可能是最通用且记录最完整的解决方案,让我像以前一样继续将错误插入组件的html中。它还让我继续使用loading = true,loading = false html动画。

因此,我最终得到3个状态属性,数据,错误和加载。它似乎为我工作。你的旅费可能会改变。我也在使用vuex模块和命名空间,但这是一个没有这个的简化示例

//somevuexstore.js

actions: {

fetchData(context) {

    axios
        .get("api/someendpoint")
        .then(response => {
            context.commit('loading')
            context.commit('organizations', response.data)

        }).catch(error => {
            console.log(error.response.data.message || error.message)
            context.commit('error', error)
        });
},

mutations: {
organizations(state, data) {
    return state.organization = data
},

error(state, data) {
    return state.error = data
},

loading(state) {
    return state.loading = false
},

state= {

organization: [],
error: '',
loading: true
}

然后在我的component.vue中,它与我之前做的方法非常相似,只是添加了计算属性。

computed: {
...mapState({
        getError: 'error',
        getLoading: 'loading',
        getAllOrg: 'organization',
}),
}

mounted() {
      this.$store.dispatch('fetchData')
}

我的html就是这样的。

<tr v-for="value in getAllOrg" :key="value.id">
   <td>{{ value.id }}</td>
   <td>{{ value.email }}</td>
   <td>{{ value.name }}</td>
   <td>{{ value.['created-at'] | formatDate }}</td>
</tr>

我在适当的地方插入错误消息

<div v-if="getError" class="error">
   <p>{{ getError }}</p>
</div>

为加载动画,我在适当的地方使用了vue spinners程序包插入html。

<div v-if="getLoading" style="height:37px;">
    <p>
      <bar-loader class="custom-class" color="#c2c2c2" 
      getLoading="getLoading" 
      :width="130"></bar-loader>
   </p>

答案 3 :(得分:0)

我得出的结论是,它们不能总是存在处理错误的通用方法,因此必须以某种方式将它们与上下文耦合。拥有单独的api文件是一件好事,但请与上文提及的内容进行协调。 我有单独的api文件,正在执行以下操作:

//comments-api.js
export default {
    get (url, handler){
        //return the promise to further possible chains
        return axios.get(url)
            .then( response => handler.success(response.data) )
            .catch( error => handler.serverDownOrUnexpected(error.response) )
    },
}
//comments.js - vuex module
import $comments from './../../services/api/comments-api'
...
actions: {
    $comments.get(url, {
        success: (data) => commit('success_handler', data),
        serverDownOrUnexpected: (error) => commit('unexpected', error)
        //so on...
    })
}
...

在这种方法中,每当我想更改某些错误的处理方式时,我都必须在一个地方进行更改,再加上解耦代码的好处。

答案 4 :(得分:0)

承诺的力量! (加上async / await)

vue方法(mycomponent.js)

async YourAsyncMethod() {
    const payload = {key: "var"}
    const result = await axios
        .post('/your/api/endpoint', payload)
        .catch(e => {
            console.log(e.message)
        });
}

yourMethod() {
    // start axios logic
    const payload = {key: "var"}
    axios
        .post('/your/api/endpoint', payload)
        .then(response => {
            console.log(response.data)

            // start state action logic
            this.$store
                .dispatch('yourAction', payload)
                .then(add => {
                    console.log('success mutation!');
                })
                .catch(error => {
                    // error = Error object,
                    console.log('error mutation:',error.message);
                    console.log(error) // to se full error object
                });
        })
        .catch(error => {
            console.log('error axios request', error.data)
        });
}

具有状态操作(store / actions.js)

yourAction(){
    const some_logic = false;
    if (!some_logic) {
        // when return a Promisse.reject
        //you can get error with catch(e) from youtMethod
        return Promise.reject(new Error("Impressora já adicionada"))
    }
    context.commit('MUTATION_METHOD', payload);
}

使用axios

http
    .post('/your/api/endpoint', payload)
    .then(response => {
        console.log(response.data)
    })
    .catch(error => {
        console.log('error', error.data)
    });

答案 5 :(得分:0)

您可以像这样使用事件总线

import Vue from 'vue'

export const EventBus = new Vue();

然后触发错误

axios.get(...)
  .catch(function (error) {
     EventBus.$emit('error', error)
  });

答案 6 :(得分:0)

我只是用渔获物。这是我切换到vuex之前使用的同一件事。它可能是最通用且记录最完整的解决方案,让我像以前一样继续将错误插入组件的html中。它还让我继续使用loading = true,loading = false html动画。

因此,我最终得到3个状态属性,数据,错误和加载。它似乎为我工作。你的旅费可能会改变。我也在使用vuex模块和命名空间,但这是一个没有这个的简化示例

//somevuexstore.js

actions: {

fetchData(context) {

    axios
        .get("api/someendpoint")
        .then(response => {
            context.commit('loading')
            context.commit('organizations', response.data)

        }).catch(error => {
            console.log(error.response.data.message || error.message)
            context.commit('error', error)
        });
},

mutations: {
organizations(state, data) {
    return state.organization = data
},

error(state, data) {
    return state.error = data
},

loading(state) {
    return state.loading = false
},

state= {

organization: [],
error: '',
loading: true
}

然后在我的component.vue中,它与我之前做的方法非常相似,只是添加了计算属性。

computed: {
...mapState({
        getError: 'error',
        getLoading: 'loading',
        getAllOrg: 'organization',
}),
}

mounted() {
      this.$store.dispatch('fetchData')
}

我的html就是这样的。

<tr v-for="value in getAllOrg" :key="value.id">
   <td>{{ value.id }}</td>
   <td>{{ value.email }}</td>
   <td>{{ value.name }}</td>
   <td>{{ value.['created-at'] | formatDate }}</td>
</tr>

我在适当的地方插入错误消息

<div v-if="getError" class="error">
   <p>{{ getError }}</p>
</div>

为加载动画,我在适当的地方使用了vue spinners程序包插入html。

<div v-if="getLoading" style="height:37px;">
    <p>
      <bar-loader class="custom-class" color="#c2c2c2" 
      getLoading="getLoading" 
      :width="130"></bar-loader>
   </p>

答案 7 :(得分:0)

在 Vuex 中添加“上次加载”状态,并观察 root 中的变化。

这可能看起来很笨重和复杂,但它是合乎逻辑的并且很好地分离了组件。

奖励:您会立即知道您是否已加载数据并尝试成功!

答案 8 :(得分:0)

现在可在 VUE 3 组合 API 中使用,并得到了独特的解决

我们可能会使用 AXIOS 拦截器作为 documentation 来设置所需的配置,然后在 VUE 中

import {onErrorCaptured, ref} from "vue";

setup(){
    let errors = ref(null)
    onErrorCaptured((error)=>{
         // checking for server response first
         errors.value = error.response?Object.values(error.response.data)[0]:error.message
    })
    return{errors}
}