umi-request如何处理状态码500返回的结果信息?

Created on 2 Sep 2019  ·  13Comments  ·  Source: umijs/umi

我们团队将api异常处理的状态码设置为500(个人觉得无法理解)
所以我得从状态为500的api中拿取到请求的结果(即错误信息)

但我尝试了errorHandler去获取response,但是结果只有api的状态信息,然后我尝试去拦截器中去获取response,但仍然和errorHeandler中一致,为Response接口类型
image
再则通过中间件获取response,但只有200状态码时才能获取到。
是否暂时不支持500的结果返回?

谢谢

pkg(umi-request)

Most helpful comment

umi-request 会根据 responseType (默认为 json)对 http 响应结果 response 做解析生成 data,然后根据 Response 状态码是否处于[200, 300) 之前来确定是否正常返回还是抛出异常,如果抛出异常 error,会将 response、data 存在 error 对象中,所以可以通过 errorHandler 拿到,示例:

const errorHandler = error => {
  const { response = {}, message = '', data = {} } = error;
  const { status = 500 } = response;
  if (message === 'http error' && status === 500) {
    console.log(data); // 获取 response 解析后的数据
    // 也可以自行对 response 做解析
    const clone = response.clone();
    clone.text()
    .then(data => console.log(JSON.parse(data)))
  }
}

All 13 comments

@chenjsh36 请看下。

const errorHandler = error => {
const { response } = error;

if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
const { status, url } = response;
。。。。
}

这个status拿不到状态信息吗?

const errorHandler = error => {
const { response } = error;

if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
const { status, url } = response;
。。。。
}

这个status拿不到状态信息吗?

状态信息可以拿到得,
我是想拿到response里面得错误信息
但你说得只能拿到api请求的状态

umi-request 会根据 responseType (默认为 json)对 http 响应结果 response 做解析生成 data,然后根据 Response 状态码是否处于[200, 300) 之前来确定是否正常返回还是抛出异常,如果抛出异常 error,会将 response、data 存在 error 对象中,所以可以通过 errorHandler 拿到,示例:

const errorHandler = error => {
  const { response = {}, message = '', data = {} } = error;
  const { status = 500 } = response;
  if (message === 'http error' && status === 500) {
    console.log(data); // 获取 response 解析后的数据
    // 也可以自行对 response 做解析
    const clone = response.clone();
    clone.text()
    .then(data => console.log(JSON.parse(data)))
  }
}

@chenjsh36 如果拿不到errorHandler 可能会是什么问题?
业务中,登录接口账号密码错误的情况下会抛403,但是响应拦截器的option里没有errorHandler,且在控制台抛出ResponseError: http error 的错误。

@chenjsh36 如果拿不到errorHandler 可能会是什么问题?
业务中,登录接口账号密码错误的情况下会抛403,但是响应拦截器的option里没有errorHandler,且在控制台抛出ResponseError: http error 的错误。

不用在拦截器里操作的,只需要在 errorHandler 里对异常做处理即可,示例:

import { extend } from 'umi-request';

const errorHandler = error => {
  const { response = {}, message = '', data = {} } = error;
  const { status = 500 } = response;
  if (message === 'http error' && status === 500) {
    return data; // 对 status 为 500 的接口也返回 data
  }
}
const request = extend({
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

...
// 请求响应状态 500,响应内容为 { hello: 'world' } 的接口
const data = await request('/api/hello');
console.log(data); // {hello: 'world'};

@chenjsh36 如果拿不到errorHandler 可能会是什么问题?
业务中,登录接口账号密码错误的情况下会抛403,但是响应拦截器的option里没有errorHandler,且在控制台抛出ResponseError: http error 的错误。

不用在拦截器里操作的,只需要在 errorHandler 里对异常做处理即可,示例:

import { extend } from 'umi-request';

const errorHandler = error => {
  const { response = {}, message = '', data = {} } = error;
  const { status = 500 } = response;
  if (message === 'http error' && status === 500) {
    return data; // 对 status 为 500 的接口也返回 data
  }
}
const request = extend({
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

...
// 请求响应状态 500,响应内容为 { hello: 'world' } 的接口
const data = await request('/api/hello');
console.log(data); // {hello: 'world'};

我确实做了如您示例的errorHandler初始化,但是在出问题的login请求options里没有拿到errorHandler,而在登录成功后的请求中都带有errorHandler。
现在暂时的解决方式是,手动在请求拦截器里添加了errorHandler,已能捕获到错误。
请问这里的extend初始化有什么顺序说法吗?

const errorHandler = error => {
  console.log('errorHandler');
  const { response } = error;
  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;
    if (response.status === 401) {
      return;
    } else {
      notification.error({
        message: `请求错误 ${status}: ${url}`,
        description: errorText,
      });
    }
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常,无法连接服务器',
      message: '网络异常',
    });
  }

const umi_request = extend({
  errorHandler,
  // 默认错误处理
  headers: {
    authorization: `Bearer ${localStorage.getItem('access_token')}`,
  },
});

// 这里在请求拦截里做了一下token的刷新
umi_request.interceptors.request.use((url, options) => {
  console.log(options) // 这里login的options里没有errorHandler,所以在下面手动加了暂时解决问题
  return {
    options: {
      ...options,
      errorHandler,
      interceptors: true,
      headers: { authorization: `Bearer ${localStorage.getItem('access_token')}` },
    },
  };
});

@in-vane-yuhu
我也遇到这个问题,发现是因为登录里直接用的 umi-request 而不是封装后的 request,改一下就好了。
不知道模板代码里为什么这样写

@hhking
点点点
还真是...你真的细心
感谢🙏

@chenjsh36 如果拿不到errorHandler 可能会是什么问题?
业务中,登录接口账号密码错误的情况下会抛403,但是响应拦截器的option里没有errorHandler,且在控制台抛出ResponseError: http error 的错误。

不用在拦截器里操作的,只需要在 errorHandler 里对异常做处理即可,示例:

import { extend } from 'umi-request';

const errorHandler = error => {
  const { response = {}, message = '', data = {} } = error;
  const { status = 500 } = response;
  if (message === 'http error' && status === 500) {
    return data; // 对 status 为 500 的接口也返回 data
  }
}
const request = extend({
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

...
// 请求响应状态 500,响应内容为 { hello: 'world' } 的接口
const data = await request('/api/hello');
console.log(data); // {hello: 'world'};

@chenjsh36 如果拿不到errorHandler 可能会是什么问题?
业务中,登录接口账号密码错误的情况下会抛403,但是响应拦截器的option里没有errorHandler,且在控制台抛出ResponseError: http error 的错误。

不用在拦截器里操作的,只需要在 errorHandler 里对异常做处理即可,示例:

import { extend } from 'umi-request';

const errorHandler = error => {
  const { response = {}, message = '', data = {} } = error;
  const { status = 500 } = response;
  if (message === 'http error' && status === 500) {
    return data; // 对 status 为 500 的接口也返回 data
  }
}
const request = extend({
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

...
// 请求响应状态 500,响应内容为 { hello: 'world' } 的接口
const data = await request('/api/hello');
console.log(data); // {hello: 'world'};

这个方法确实可行,请教另外一个问题:这种非200的状态码如何让错误不在控制台中显示?

@chenjsh36 如果拿不到errorHandler 可能会是什么问题?
业务中,登录接口账号密码错误的情况下会抛403,但是响应拦截器的option里没有errorHandler,且在控制台抛出ResponseError: http error 的错误。

不用在拦截器里操作的,只需要在 errorHandler 里对异常做处理即可,示例:

import { extend } from 'umi-request';

const errorHandler = error => {
  const { response = {}, message = '', data = {} } = error;
  const { status = 500 } = response;
  if (message === 'http error' && status === 500) {
    return data; // 对 status 为 500 的接口也返回 data
  }
}
const request = extend({
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

...
// 请求响应状态 500,响应内容为 { hello: 'world' } 的接口
const data = await request('/api/hello');
console.log(data); // {hello: 'world'};

@chenjsh36 如果拿不到errorHandler 可能会是什么问题?
业务中,登录接口账号密码错误的情况下会抛403,但是响应拦截器的option里没有errorHandler,且在控制台抛出ResponseError: http error 的错误。

不用在拦截器里操作的,只需要在 errorHandler 里对异常做处理即可,示例:

import { extend } from 'umi-request';

const errorHandler = error => {
  const { response = {}, message = '', data = {} } = error;
  const { status = 500 } = response;
  if (message === 'http error' && status === 500) {
    return data; // 对 status 为 500 的接口也返回 data
  }
}
const request = extend({
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

...
// 请求响应状态 500,响应内容为 { hello: 'world' } 的接口
const data = await request('/api/hello');
console.log(data); // {hello: 'world'};

这个方法确实可行,请教另外一个问题:这种非200的状态码如何让错误不在控制台中显示?

你说的是响应异常时浏览器默认在控制台打印的异常信息,这个是浏览器自身默认行为来的,方便开发者调试,一般无法禁止,而且用户正常不会打开控制台的吧。

如果发生错误的状态码, 如404, 500, 在errorHandler 的error中无法获取信息, 为null

如果发生错误的状态码, 如404, 500, 在errorHandler 的error中无法获取信息, 为null

如果加相应拦截器的话,errorHandler的error就为null;反之去掉,就能显示

Was this page helpful?
0 / 5 - 0 ratings