npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vtex/node-error-report

v0.0.3

Published

Error parsing, serialization, sanitizing and reporting

Downloads

20,964

Readme

node-error-report

Version

This package is used as base for error parsing logic on node-vtex-api and vtex-toolbelt.

Install

$ yarn global add @vtex/node-error-report

API

The ErrorReportBase is a wrapper for node errors that provides features like error serialization, sanitization and error parsing (in case of request errors, for example).

Instantiation

It has the following constructor arguments:

kind [required]

This is supposed to be an error code to make error identification on a logs backend easier.

originalError [required]

This is the originalError to be wrapped by the ErrorReportBase - it will try to parse meaningful information on the error and add it to the parsedInfo instance variable.

config [required]

Configures error serialization aspects:

  • Max string size on each field.
  • Max object depth.

message [optional]

ErrorReportBase uses originalError.message as default error message. This allows to override it.

details [optional]

This is a object with additional details on the error, can be used in cases like:

try {
  content = readFileSync(filename)
} catch(err) {
  new ErrorReportBase({
      ...,
      details: {
          filename
      }
  })
}

Note that this is useful because sometimes errors thrown by standard functions doesn't help us to pinpoint the issue.

Serialization

The serialization task is done by the toObject method on ErrorReportBase. It will:

  • Remove circular references.
  • Truncate strings bigger than config.maxStringLength.
  • Sanitize jwt tokens (the token identification logic right now is not that good).

Also, the toObject will have error metadata, the details provided by whom instantiated the error, the original error stack, message and parsed info.

Error parsing

For now just axios request errors are parsed - some key information on the request are stripped out to a object (code).

Also it's possible to create parseable errors by implementing the ParseableError interface, e.g.:

export class EventSourceError extends Error implements ParseableError {
  public event: any
  public eventSourceInfo: EventSourceInfo
  constructor(event: any, eventSourceInfo: EventSourceInfo) {
    super(`SSE error on endpoint ${eventSourceInfo.url}`)
    this.eventSourceInfo = eventSourceInfo
    this.event = { ...event }
  }

  public getDetailsObject() {
    return {
      event: this.event,
      eventSourceInfo: this.eventSourceInfo,
    }
  }
}

When instantianting a ErrorReportBase and providing an EventSourceError object as the originalError, the parseInfo on ErrorReportBase will be the content returned by getDetailsObject.

Parsed info type guards

Some typescript type guards implemented are also exported:

  • isRequestInfo: Checks if the parsedInfo instance variable is the result of a request parsing.
  • isInfraErrorData: Checks if the requestInfo.response.data is a VTEX IO infra error (these errors can be used to improve the error report).

Helpers

createErrorReportBaseArgs

This function abstracts away some instantiation logic, it allows the function user to optionally specify the kind (if not specified a generic kind will be used - GenericError or RequestError) and abstracts away the config creation. The configs will be provided by:

maxStringLength: ErrorReportBase.MAX_ERROR_STRING_LENGTH
maxSerializationDepth: ErrorReportBase.MAX_SERIALIZATION_DEPTH

The ErrorReportBase allow these default values to be changed, e.g.:

ErrorReportBase.MAX_ERROR_STRING_LENGTH = 2048

Usage example

The ErrorReportBase class is supposed to be extended with functions for reporting the error to a log/tracing backend, for example:

export class ErrorReport extends ErrorReportBase {
  public static create(args: ErrorReportCreateArgs) {
    return new ErrorReport(createErrorReportBaseArgs(args))
  }

  constructor(args: ErrorReportBaseConstructorArgs) {
    const { workspace, account } = SessionManager.getSingleton()

    const env: ErrorEnv = {
      account,
      workspace,
      toolbeltVersion: pkg.version,
      nodeVersion: process.version,
      platform: getPlatform(),
      command: process.argv.slice(2).join(' '),
    }

    super({
      ...args,
      details: {
        ...args.details,
        env,
      },
    })
  }

  public sendToTelemetry() {
    if (!this.isErrorReported()) {
      TelemetryCollector.getCollector().registerError(this)
      this.markErrorAsReported()
    }

    return this
  }
}

The ErrorReportBase class keeps track of the report state of the error, to avoid sending the same originalError to the backend twice - that's the role of the methods isErrorReported and markErrorAsReported. These functions add metadata to the originalError as well, so if the same originalError is passed to another ErrorReportBase instance, the report state will be maintained.

Metrics

ErrorReportBase exposes the following metrics that can be reported to a metrics/logs backend and accessed via errorReporObj.metadata.metrics:

instantiationTime

On its instantiation, the ErrorReportBase class clones and sanitizes some fields from the arguments provided, for example:

  • All info extracted from RequestErrors are sanitized and cloned.
  • The details object is sanitized and cloned. This is done because later uses of these objects (or sub-objects) could be affected if ErrorReportBase didn't cloned them and changed anything (for example, it could sanitize the Authorization header, then later uses of the same request config would end up with auth errors).

But this may be costly (who knows?). Because of this, ErrorReportBase exposes the instantiationTime metric.