Parsing body in response that is a non-200 Status Code - Typescript/Vue

162 Views Asked by At

I have an API call that I am making in my app. In some cases the API will return a non-200 status code with a user friendly message in the body of the response. I have set up a try catch block when calling the API. I am facing some challenges getting the body if a non status is returned.

Response body is a json string.

// example response 403 status code ....
{
"message": "Houston we have a problem"
}
    try {
      const results = [];
      let result = [];
      const response = await ky.get(`${this.state.api_base_url}/${path_parts.join("/")}?${query_parts.map(x => `${x.key}=${x.value}`).join("&")}`);
      result = await response.json();
      context.commit("set200response", result);

    } catch (err) {

    // I have tried each of the following without success
    // this returns undefined
    console.error("Non 200 Message", (err as any).response.data.message);
    console.error("Non 200 Message", (err as any).response.data);
    // this returns the promise object but I can not access its properties 
    console.error((err as any).response.json());

    //this returns the generic message for a non 200 status
    console.error("Generic Message", (err as any).message);
    } finally {
        context.commit("setLoading", false);
    } 
    }
1

There are 1 best solutions below

0
Roman On

By default ky return error from response.statusText. You need to change the error message in the interceptor.

This can be done as follows:

import ky, { HTTPError } from 'ky';

const baseApi = ky.create({
  prefixUrl: 'https://your_base_api_url',
});

const errorInterceptor = async (error: HTTPError) => {
  const { response } = error;

  const contentType = response.headers.get('content-type');
  if (contentType?.indexOf('application/json') !== -1) {
    error.message = await response.json();
  } else {
    error.message = await response.text();
  }
  return error;
};

const api = baseApi.extend({
  hooks: {
    beforeError: [errorInterceptor],
  },
});

Then in your components file:

import api from 'file_above'

const query_parts = {
  key1: 'param1'
  key2: 'param2'
}

try {
  const result = await api.get(path_parts, { searchParams: query_parts }).json();
  context.commit('set200response', result);
} catch (err: any) {    
  //this returns the message for a non 200 status
  console.error('Error Message:', err?.message);
} finally {
  context.commit('setLoading', false);
}