Get EXN Message or HTTP Status Code from Promise.catch?

Right now I’ve an exception in a promise catch clause from bs-axios… that looks like this:

Axios.postData(...) 
     ->Promise.then(response => {
          Js.log("do cool things and stuff")
          Promise.resolve(true)
     ->Promise.catch(error => {
          Js.log(error) 
          // {"RE_EXN_ID": "Promise.JsError/2", "_1": [Error: Request failed with status code 429]}
          Promise.resolve(false)
      })

// {“RE_EXN_ID”: “Promise.JsError/2”, “_1”: [Error: Request failed with status code 429]}

The type on error is EXN not Js.Exn.t.

I read all the documentation I could about EXN rescript types and understand that there is a difference between Rescript Exceptions and JS Exceptions.

But what I don’t understand is how to extract any sort of meaning or usefulness from Rescript EXN, like an HTTP STATUS CODE or MESSAGE.

I’m not sure where else to look, so some help would be appreciated, thanks. :wink:

To extract Js.Exn.t from EXN, you can do this:

->Promise.catch(error => {
  switch error {
    | Promise.JsError(jsExn) => ...
    | _ => ... this is not a JsError ...
  }
})

Then, the bs-axios docs suggest that you cast the error into an 'a type and extract fields unsafely. Same can be done in ReScript but the syntax is a bit different from Reason.

But I would do it more safely:

@get external getResponse: Js.Exn.t => option<Axios.response<'a, 'b>> = "response"

...->Promise.catch(error => {
  switch error {
    | Promise.JsError(jsExn) => switch jsExn->getResponse {
        | Some(response) => Js.log(response["status"])
        | None => Js.log("No response property")
    }
    | _ => Js.log("Not a JS error") 
  }
})

Not sure the above code is correct, as I never used axios before, but you get the idea.

3 Likes

Brilliant. Thank you! :fire: :fist_right:

1 Like