@cstan/api-error-reporter
TypeScript icon, indicating that this package has built-in type declarations

1.0.0 • Public • Published

api-error-reporter

A CommonJS module designed for a specific API convention. I takes calls from hapi routes or a custom DB interface to report errors/exceptions by converting them into a Boom error, sending relevant information to a logging module, @cstan/api-logger, then sends customized error back to the user interface where it can be displayed in a pop up, we use Primevue Toast. There are 16 types of errors that are handled, often in a custom way. Each type of error will be explained below.

The module depends on @cstan/api-logger and @hapi/boom but they are loosely coupled and do not require that you use this error reporter with any other specific apps or modules. It does require a configuration object. We pass the object into the module via a method as demonstrated below. While our config object contains all configuration data for the API you can use a minimal config object as shown here:

const cfg = {
  logPath: "/home/cstan/api/logs/"
};

We will use, for the sake of simplicity, the above declaration in the example to follow.

Installation

npm install @cstan/api-error-reporter

Use

const rptErr = require("@cstan/api-error-reporter");
rptErr.setConfig(cfg);

The configuration will be passed to @cstan/api-logger so that it can write errors to, in this case: /home/cstan/api/logs/errors/yyyymm.log where yyyy will be replaced with the current year and mm will be replaced with the current month. This way every month has its own log file.

Below is a sample of how this module is used in a API application when attempting to delete a row from a MySQL database. Note that there are two cases where this module is called. Once to report an error of an invalid UID is used to identify the row to be deleted and the other is when the database server reports an error.

const remove = async function (request, h, table) {
  const pool = request.mysql.pool;
  if (!validateLuid(request.query.id)) {
    return rptErr.invalidIdSubmitted(request.query.id);
  }
  try {
    await pool.query("DELETE FROM ?? WHERE `id` = ?", [
      table,
      request.query.id,
    ]);
  } catch (err) {
    return rptErr.dbAccess(err, {
      DeleteFrom: table,
      RowId: request.query.id,
    });
  }
  // deletion successful
  return h.response("okay");
};

Note that the arguments are different for each type of error. In the case of the 'invalidIdSubmitted' error the invalid id is the argument. In the case of the error generated by the MySQL server there are two arguments: the error reported by MySQL and an object with whatever descriptive information you would like in the error log, in this case the table from which the deletion was to occur and the identifier used to select the row to be deleted. The coder can include whatever information they desire or the second argument my be omitted.

Every method of @cstan/api-error-reporter returns a boom error that has been modified so that if your front end traps the error it can look for 'error.response.data.err_msg'. The err_msg is an object created by @cstan/api-error-reporter. Example:

error.response.data.err_msg: { severity: 'error', summary: 'Server Error', detail: 'Failure while accessing database.' }

This configuration is exactly what the Primevue Toast pop up uses for its argument so we can use it directly to display the error to the user.

Now to examine each method:

rptErr.dbAccess(err, data)

Arguments: 'err' is an error generated by the database server 'data' is an object created in the calling module with descriptive informatiom

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: 'error',
    summary: 'Server Error',
    detail: 'Failure while accessing database.'
  }

rptErr.invalidCredentials()

Arguments: none

Logged: not logged here

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "warn",
    summary: "Failed Login",
    detail: "Email or password is invalid.",
  }

rptErr.unauthorizedRequest(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "warn",
    summary: "Failed to complete request",
    detail: "You are not authorized for request made.",
  }

rptErr.invalidDataSubmitted(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "warn",
    summary: "Submitted data is invalid",
    detail: "Data submitted was invalid for request made.",
  }

rptErr.invalidSession()

Arguments: none

Logged: Date and time, error name and stack

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "warn",
    summary: "Session expired or corrupted",
    detail: "Please log in again.",
  }

rptErr.phNoNotFound(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "warn",
    summary: "Invalid Phone Number",
    detail: "Phone number not found in profile.",
  }

rptErr.emailNotFound(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "warn",
    summary: "Invalid Email",
    detail: "Email not found in profile.",
  }

rptErr.invalidAccessCode(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "warn",
    summary: "Invalid Access Code",
    detail: "The access code submitted was invalid.",
  }

rptErr.donorsNotFound()

Arguments: none

Logged: Date and time, error name and stack

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "info",
    summary: "No Parent Organizations",
    detail: "No donor organizations were found in database.",
  }

rptErr.insertNotAllowed(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "error",
    summary: "Data Insertion Error",
    detail: "Submitted data already had an ID.",
  }

rptErr.invalidProfileUpdate(user_id)

Arguments: 'userid' is an string indicating the database _id of the current user

Logged: Date and time, error name and stack and the user's id.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "error",
    summary: "Access forbidden",
    detail: "You may only update your own profile.",
  }

rptErr.staffNotFound(data)

Arguments: 'data' is an object created in the calling module with descriptive data

  {
    User: 'db id of user',
    FirstName: 'first few letters of first name of staff member used for search',
    LastName: 'first few letters of last name of staff member used for search'
  }

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "warn",
    summary: "Match not found",
    detail: "Unable to find matching name(s) for your criteria.",
  }

rptErr.userIdNotFound(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "error",
    summary: "Data Update Error",
    detail: "This update data ID not found in database.",
  }

rptErr.invalidIdSubmitted(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "error",
    summary: "Invalid ID",
    detail: "The ID submitted was not a valid LUID.",
  }

rptErr.validationError(data)

Arguments: 'data' is an object created in the calling module with descriptive data

Logged: Date and time, error name and stack and the contents of the data object.

Returned: Boom error object with Primevue Toast object attached:

  {
    severity: "error",
    summary: "Validation error",
    detail: "The data you submitted does not conform to validation rules.",
  }

rptErr.unhandledException(error)

Arguments: error is an Error object generated by the server and not caught elsewhere.

Logged: Date and time, error name and stack

Returned: The error is converted to a Boom error and returned with the Primevue Toast object:

  {
    severity: "error",
    summary: "Unhandled exception",
    detail: "Unhandled exception: see error log for details.",
  }

Readme

Keywords

none

Package Sidebar

Install

npm i @cstan/api-error-reporter

Weekly Downloads

1

Version

1.0.0

License

ISC

Unpacked Size

17.7 kB

Total Files

4

Last publish

Collaborators

  • cstanton48