Home > front end >  Axios & Typescript give error from promise rejection a type
Axios & Typescript give error from promise rejection a type

Time:10-25

The problem I'm currently facing is that I can't use a returned error from a promise rejection because it is not typeable with Typescript. For example when a signup request fails because the username is already taken I return a 400 with the message username already taken. But I can't access the message from the error because the error object from a try catch can't be typed.
Is there any way axios can handle this situation and can give me access to the error obejct with a custom type?
Or should I just create an error object under the data and either return it as null when the server has a 200 or return an error obejct?

Example:

export interface ErrorRes {
  statusCode: number;
  error: string;
  message: string;
}

export interface ISignupRes {
  token: string;
  user: IUser;
  message: string;
}
const handleSignUp = async () => {
  setLoading(true)
  try {
    const { data, status }: { data: ISignupRes; status: number } =
      await coreApi.post('/auth/signup', {
        email,
        username,
        firstname,
        lastname,
        password,
      })
    if (status === 200) {
      Storage.save(true, 'token', data.token)
      addNotification({
        type: 'success',
        message: data.message,
      })
    } else {
      // this never get's called because if the response returns an error it get's catched
      addNotification({
        type: 'error',
        message: data.message,
      })
    }
    setLoading(false)
  } catch (error) {
    // the error is of type `unkown` to I can't access `error.message`
    setLoading(false)
    addNotification({
      type: 'error',
      message: error.message,
    })
  }
}

CodePudding user response:

Typescript doesn't have a way to verify that axios errors are the only possible errors that could be thrown by your code, so the error in a typescript catch block is always either unknown or any. Your compiler settings apparently prefer unknown.

To treat the error as something else you either need to put in some code to check what type of thing was thrown, or you need to use a type assertion to insist to typescript that you know what the type is. Fortunately, the axios library includes a helper function that can do the check for you, and it has appropriate types to narrow down the error object:

} catch (error) {
  if (axios.isAxiosError(error) {
    // inside this block, typescript knows that error's type is AxiosError<any>
    setLoading(false)
    addNotification({
      type: 'error',
      message: error.message,
    })
  } else {
    // In this block, error is still of type `unknown`
  }
}
  • Related