Get CustomErrorMessage by http request using ky library

474 Views Asked by At

I am using React and Express to create a web application.
However, the response to a request using the ky library will contain a default message.
How do I get a custom message?
By the way, this works on Postman & axios library.

//Custom Error

class HttpException extends Error {
  status: number;
  message: string;
  constructor(status: number, message: string) {
    super(message);
    this.status = status;
    this.message = message;
  }
}

export default HttpException;
//Express

import HttpException from '../exceptions/HttpException';

if (!Object.keys(result).length) throw new HttpException(404, "User does not exist")
//Express error handling middleware

export const errorMiddleware = (err: HttpException, req: express.Request, res: express.Response, next: express.NextFunction) =>{
  const status = err.status || 500;
  const message = err.message || 'Something went wrong';
  res
    .status(status)
    .send({
      status,
      message,
    })
}
//React
import ky from 'ky'

const customKy = ky.create({
  prefixUrl: process.env.NEXT_PUBLIC_API_HOST,
  credentials: "include",
  headers: { 'Content-Type': 'application/json' },
});

try {
      const result: any = await customKy.post("path", { json: data }).json()
    } catch (err: any) {
      console.log(err.response.status)
      console.log(err.response.message)
    }
//result console
login.tsx:28 404
login.tsx:29 undefined
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.

import ky from 'ky'

const baseApi = ky.create({
  prefixUrl: process.env.NEXT_PUBLIC_API_HOST,
  credentials: "include",
  headers: { 'Content-Type': 'application/json' },
});

const errorInterceptor = async (error) => {
  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 React component:

import api from 'file_above'

try {
      const result: any = await api.post("path", { json: data }).json()
    } catch (err: any) {
      console.log(err?.response?.status)
      console.log(err?.response.message)
    }