GET JavaScript Error Message

Correctly Handle JavaScript Error Messages

In the post about REST API Filtering we have getFilterBy method in BaseRepository that calls getSequelizeWhereClause function and returns result. The call is wrapped up in try…catch block, so when an error is thrown, it gets transformed into an API error and get re-thrown. The message from the original error is assigned to the API error message.

protected getFilterBy(filterBy: string): Record<string, any> {
    try {
      return getSequelizeWhereClause(
        parse(filterBy),
        this.allowedFilterByFields
      );
    } catch (error: any) {
      throw new ApiError({
        name: "FILTER_BY_ERROR",
        message: error.message,
        status: 400,
        code: "ERR_FTB",
      });
    }
  }

Implement JavaScript Error Message Handling

We, actually cheated here and casted the original error as type any. If we remove the casting, the error becomes type unknown and typescirpt is now complaining that we are trying to access message property on the error of unknown type. The reason for error to be type of unknown is that in JavaScript anything can be thrown as an error. If we put it in MDN words: The throw keyword can be followed by any kind of expression. So typescript is warning us that property messagemay not be on the error. Since most of the errors in function getSequelizeWhereClause we threw ourselves as part of flow control, we should be relatively safe here to assume the error will have message property. However, we can’t be quite sure about parse function of Liqe library. It’s better to be on the safe side and fix the issue.

Let’s go in to utils/functions.ts file and create function getErrorMessage.

export function getErrorMessage(error: unknown): string {
  if (error instanceof Error) {
    return error.message;
  }
  if (error && typeof error === "object" && "message" in error) {
    return String(error.message);
  }
  if (typeof error === "string") {
    return error;
  }
  return "An error occurred";
};

First the code checks if the error is type of Error if so, it returns message property of the error.

Next the code checks if error is type of object and has message property. Oddly enough null in javascript is also an object. So we need to check if error first, to make sure error is not null. If error is an object with message property, error message is casted to string and returned.

Next the code checks if error is a string and returns it.

Finally if all checks fail, the function returns a generic error message.

protected getFilterBy(filterBy: string): Record<string, any> {
    try {
      return getSequelizeWhereClause(
        parse(filterBy),
        this.allowedFilterByFields
      );
    } catch (error) {
      throw new ApiError({
        name: "FILTER_BY_ERROR",
        message: getErrorMessage(error),
        status: 400,
        code: "ERR_FTB",
      });
    }
  }
}

Now, typescript is happy and we are as well. Thank you for watching and I will see you in the next video.

Share this article

Similar Posts