You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Axios拦截器Promise拒绝处理异常:409错误无法传递至组件

Hey there! Let's break down what's going on with your Axios error handling and walk through the right way to fix it.

First, Why Your Original Setup Had Issues

Let's start with the core problem: when you returned Promise.reject(error) from the interceptor, your component's catch block got undefined. The most likely culprit is a typo in your request interceptor's error handler:

// You used `error.message` but the parameter is named `err`!
vue.$eventBus.$emit('toastMessageHandler', {message: error.message, type: 'error'});

This throws a ReferenceError (since error isn't defined here), which can override or corrupt the original error object being passed down the chain. That's why your component ended up with undefined instead of the 409 error.

As for why wrapping the error in an object (Promise.reject({error})) worked: you're explicitly packaging the original error into a new object, which avoids the ReferenceError from the typo and ensures something gets passed to the component's catch block. But this is a workaround—let's fix the root issue properly.

How Axios Interceptor Error Handling Works

Axios interceptors rely on Promise chaining to pass errors along. For response interceptors:

  • If you return Promise.reject(error), the error object flows directly to the next catch block in your component.
  • If you don't return a rejected Promise (e.g., you return a plain value or forget to return anything), Axios will convert the error into a resolved Promise, and your component's catch won't trigger at all.

Wrapping the error in an object isn't necessary unless you want to add extra metadata to the error. The cleanest approach is to pass the original error object directly.

Let's adjust your code step by step:

1. Fix the Request Interceptor Typo

First, correct the reference to the error parameter in the request interceptor:

export function apiFactory(vue, $security) {
  const $http = axios.create({ baseURL: process.env.API_URL });
  
  $http.interceptors.request.use(function (config) {
    const token = $security.loginFrame.getToken();
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  }, function (err) {
    // Use `err` instead of `error` here
    vue.$eventBus.$emit('toastMessageHandler', {message: err.message, type: 'error'});
    return Promise.reject(err);
  });
  
  $http.interceptors.response.use(function (response) {
    return response;
  }, function (error) {
    if (error.response && error.response.status === 401) {
      vue.$eventBus.$emit('authErr', error);
    } else if (error.response && error.response.status === 403) {
      alert('you are not authorized, please contact EM support');
    } else if (error.response && error.response.status !== 409){
      vue.$eventBus.$emit('toastMessageHandler', {message: error.message, type: 'error'});
    }
    // Pass the original error directly to the component's catch block
    return Promise.reject(error);
  });
  
  // Don't forget to return the $http instance!
  return $http;
}

2. Clean Up Component Error Handling

Your component code can stay mostly the same, but add safeguards for cases where error.response might not exist (like network errors) and make sure to reset loading state in the catch block:

async addTag() {
  if (this.newTag.length > 0) {
    this.loading = true
    this.$emit('loading', true)
    const payload = { term: this.newTag, term_type: this.type, partner_code: this.query.partner_code, language: this.query.language }
    try {
      await this.apiFacade.createSearchTerm(payload);
      this.$emit('loading', false)
      this.loading = false
      this.tags.unshift(this.newTag)
      this.newTag = ''
      this.$eventBus.$emit('toastMessageHandler', { message: this.$t(`search_terms.add_success`), type: 'info' });
    } catch (e) {
      // Use optional chaining to avoid errors if e.response doesn't exist
      if (e?.response?.status === 409) {
        this.$eventBus.$emit('toastMessageHandler', { message: this.$t(`search_terms.duplicate_term`), type: 'error' });
      } else {
        // Handle unexpected errors (e.g., network issues)
        console.error('Unexpected error creating search term:', e);
      }
      // Always reset loading state, even if there's an error
      this.$emit('loading', false)
      this.loading = false
    }
  }
}

Extra Tips

  • Extend errors if needed: If you want to add custom metadata to errors in the interceptor, modify the original error object instead of wrapping it:
    error.customMessage = "Something went wrong with your search term";
    return Promise.reject(error);
    
    Then access it in the component with e.customMessage.
  • Avoid silent failures: Always log unexpected errors in the component's catch block to debug issues quickly.

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:06:43