Get a catch block error message with TypeScript

Get a catch block error message with TypeScript

[ad_1]

Alrighty, let’s discuss this:

const reportError = ({message}) => {
  // ship the mistake to our logging provider...
}

check out {
  throw new Error('Oh no!')
} catch (error) {
  // we will continue, however let's record it
  reportError({message: error.message})
}

Just right thus far? Neatly, that is as a result of that is JavaScript. Let’s throw TypeScript at
this:

const reportError = ({message}: {message: string}) => {
  // ship the mistake to our logging provider...
}

check out {
  throw new Error('Oh no!')
} catch (error) {
  // we will continue, however let's record it
  reportError({message: error.message})
}

That reportError name there is not glad. In particular it is the error.message
bit. This is because (as of lately) TypeScript defaults our error kind to
unknown. Which is in point of fact what it’s! On the planet of mistakes, there may be no longer a lot
promises you’ll be offering in regards to the kinds of mistakes which might be thrown. Actually,
this is identical explanation why you’ll’t give you the kind for the .catch(error => {})
of a promise rejection with the promise generic
(Promise<ResolvedValue, NopeYouCantProvideARejectedValueType>). Actually, it
would possibly no longer also be an error that is thrown in any respect. It may well be as regards to
the rest:

throw 'What the!?'
throw 7
throw {wut: 'is that this'}
throw null
throw new Promise(() => {})
throw undefined

Severely, you’ll throw the rest of any kind. In order that’s simple proper? Lets
simply upload a kind annotation for the mistake to mention this code will simplest throw an
error proper?

check out {
  throw new Error('Oh no!')
} catch (error: Error) {
  // we will continue, however let's record it
  reportError({message: error.message})
}

Now not so speedy! With that you can get the next TypeScript compilation error:

Catch clause variable kind annotation will have to be 'any' or 'unknown' if specified. ts(1196)

The cause of it’s because even if in our code it seems like there is no
manner anything may well be thrown, JavaScript is kinda humorous and so its
completely imaginable for a 3rd celebration library to do one thing funky like
monkey-patching the mistake constructor to toss stuff other:

Error = serve as () {
  throw 'Plant life'
} as any

So what is a dev to do? The easiest they are able to! So how about this:

check out {
  throw new Error('Oh no!')
} catch (error) {
  let message = 'Unknown Error'
  if (error instanceof Error) message = error.message
  // we will continue, however let's record it
  reportError({message})
}

There we cross! Now TypeScript is not yelling at us and extra importantly we are
dealing with the circumstances the place it actually may well be one thing utterly surprising.
Possibly shall we do even higher although:

check out {
  throw new Error('Oh no!')
} catch (error) {
  let message
  if (error instanceof Error) message = error.message
  else message = String(error)
  // we will continue, however let's record it
  reportError({message})
}

So right here if the mistake is not a real Error object, then we will simply stringify
the mistake and optimistically that may finally end up being one thing helpful.

Then we will be able to flip this right into a software to be used in all our catch blocks:

serve as getErrorMessage(error: unknown) {
  if (error instanceof Error) go back error.message
  go back String(error)
}

const reportError = ({message}: {message: string}) => {
  // ship the mistake to our logging provider...
}

check out {
  throw new Error('Oh no!')
} catch (error) {
  // we will continue, however let's record it
  reportError({message: getErrorMessage(error)})
}

This has been useful for me in my initiatives. With a bit of luck it is helping you as smartly.

Replace: Nicolas had
a pleasant advice for
dealing with scenarios the place the mistake object you are coping with is not a real
error. After which Jesse had
a proposal
to stringify the mistake object if imaginable. So all in combination the mixed
tips seems like this:

kind ErrorWithMessage = {
  message: string
}

serve as isErrorWithMessage(error: unknown): error is ErrorWithMessage {
  go back (
    typeof error === 'object' &&
    error !== null &&
    'message' in error &&
    typeof (error as Document<string, unknown>).message === 'string'
  )
}

serve as toErrorWithMessage(maybeError: unknown): ErrorWithMessage {
  if (isErrorWithMessage(maybeError)) go back maybeError

  check out {
    go back new Error(JSON.stringify(maybeError))
  } catch {
    // fallback in case there may be an error stringifying the maybeError
    // like with round references for instance.
    go back new Error(String(maybeError))
  }
}

serve as getErrorMessage(error: unknown) {
  go back toErrorWithMessage(error).message
}

To hand!

I feel the important thing takeaway this is to understand that whilst TypeScript has its humorous
bits, do not disregard a compilation error or caution from TypeScript simply because
you assume it is unattainable or no matter. As a rule it completely is
imaginable for the surprising to occur and TypeScript does a gorgeous just right process of
forcing you to take care of the ones not going circumstances… And you can most probably to find they are
no longer as not going as you assume.

[ad_2]

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back To Top
0
Would love your thoughts, please comment.x
()
x