{"id":15598155,"url":"https://github.com/boneskull/buggin","last_synced_at":"2025-03-26T03:32:03.941Z","repository":{"id":35963280,"uuid":"219369071","full_name":"boneskull/buggin","owner":"boneskull","description":":bug: help your users report unexpected errors originating in your buggy app :grimacing:","archived":true,"fork":false,"pushed_at":"2022-12-30T19:00:22.000Z","size":2322,"stargazers_count":3,"open_issues_count":11,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-01T03:18:39.686Z","etag":null,"topics":["bug","cli","cli-apps","error","exception","github","issue","report","ticket","uncaught","unhandled"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/boneskull.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-03T21:39:15.000Z","updated_at":"2024-11-19T20:01:43.000Z","dependencies_parsed_at":"2023-01-16T09:56:32.497Z","dependency_job_id":null,"html_url":"https://github.com/boneskull/buggin","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":"boneskull/boneskull-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boneskull%2Fbuggin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boneskull%2Fbuggin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boneskull%2Fbuggin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boneskull%2Fbuggin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boneskull","download_url":"https://codeload.github.com/boneskull/buggin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245585244,"owners_count":20639667,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bug","cli","cli-apps","error","exception","github","issue","report","ticket","uncaught","unhandled"],"created_at":"2024-10-03T01:29:12.441Z","updated_at":"2025-03-26T03:32:03.480Z","avatar_url":"https://github.com/boneskull.png","language":"JavaScript","readme":"# ![buggin logo](assets/buggin-logo-64.png) buggin\n\n\u003e help users report errors from your buggy app :grimacing:\n\n## What `buggin` Is\n\n`buggin` will intercept uncaught exceptions (and unhandled rejections) from your app, and ask the user to create a bug report. It looks something like this (customizable):\n\n![screenshot of output](assets/screenshot.png)\n\nThe new issue will be pre-filled with the exception and other info. Neat!\n\n## What `buggin` Ain't\n\n`buggin` will not attempt to determine whether or not the _exception was thrown from your code_.\n\nExceptions which originate in your package's dependencies _may_ be because of misuse (\"user error\" on your part) _or_ an actual bug in the dependency--there's really no way to tell. Either way, such a bug should be reported, so a maintainer of a package using `buggin` can triage and determine if it's an \"upstream\" problem or not.\n\n## Install\n\n**Currently, `buggin` only works with repos hosted on GitHub.**\n\nThe usual:\n\n```bash\nnpm i buggin\n```\n\n## Usage\n\n### Basic Usage\n\nYou only need to call `buggin()` once. You should do this in your CLI app entry point (the script in your `bin` prop of `package.json`).\n\n```js\n#!/usr/bin/env node\n// your other requires go here\n\nrequire('buggin')(module);\n\n// start doing stuff with args\n```\n\n### Advanced Usage\n\n#### Custom Messaging\n\nTo override the default message, create a `BugginMessageBuilder` function which accepts a `BugginMessageBuilderData` object and returns a `string`. Pass this to `buggin`'s options object via property `builder`.\n\nExample:\n\n```js\nrequire('buggin')(module, {\n  builder: ({\n    /**\n     * - `true` if error came from a unhandled rejection\n     * @type {boolean}\n     */\n    isPromise,\n    /**\n     * - Project name\n     * @type {string}\n     */\n    projectName,\n    /**\n     * - New issue URL\n     * @type {string}\n     */\n    url,\n    /**\n     * - Original error\n     * @type {Error}\n     */\n    error,\n    /**\n     * - `true` if the terminal supports color\n     * @type {boolean}\n     */\n    supportsColor\n}) =\u003e {\n  return `my custom message. please make a new issue here: ${url}`;\n});\n```\n\nNote that the error message and stack trace is _always_ displayed after `buggin`'s output. The idea is that you could use it to _conditionally change_ the message output (if needed).\n\nIf you want colors or emoji, you're on your own; `buggin` uses [ansi-colors](https://npm.im/ansi-colors) and [node-emoji](https://npm.im/node-emoji) internally.\n\nEmoji and colors are automatically stripped if the terminal lacks support. Or...that's the idea, anyway. Colors for sure.\n\n#### Use With Existing Process Event Listeners\n\nIf your module (or some module you're consuming) listens on [Process.uncaughtException](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_event_uncaughtexception) or [Process.unhandledRejection](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_event_unhandledrejection), `buggin` will refuse to set up its own listeners, print a message to `STDERR` with a warning, and exit the process.\n\nIf you'd still like to try it, pass `force: true` to the options argument:\n\n```js\nbuggin(module, {force: true});\n```\n\nBecause your own listeners could do literally anything and `buggin` can't know what it is they are doing, you'll just have to try it.\n\n#### Manual Configuration\n\nThe [auto-configuration](#auto-configuration) behavior can be overridden by a few other options:\n\n```js\n// custom package name\nbuggin(module, {name: 'custom name'});\n\n// custom package json with custom entryPoint (for stack sniffing)\nbuggin(require('/path/to/package.json'), {entryPoint: '/my/package/root/'});\n\n// path to package.json\nbuggin('/path/to/package.json');\n```\n\n#### Ignoring Certain Errors\n\nYou can pass `buggin` a selector function to help it determine whether an `Error` should be ignored by `buggin`.\n\nThis is helpful if a certain class of `Error`s are _known_ or _expected_. For example, if you expect your app to throw an `Error` with a code property of `EISDIR`, you can use the following code, and `buggin` will not intercept the exception:\n\n```js\nbuggin(module, {reject: err =\u003e err.code === 'EISDIR'});\n```\n\n\u003e Editor's Note: It's probably a better idea to actually catch these exceptions so they don't become uncaught, right?\n\nBecause of the nature of the problem--we're trying to get bug reports for _unexpected_ errors--`buggin` does not support an \"accept\" selector function, would return `true` if the `Error` was to be handled by `buggin`. To write such a function, you'd need to _know something_ about the errors you want `buggin` handle, and in so, defeating the purpose.\n\n## How It Works\n\n`buggin` does what it thinks is correct, but its understanding of what \"correct\" means is up for [further discussion](https://github.com/boneskull/buggin/issues).\n\n### Interception of Uncaught Exceptions \u0026 Unhandled Rejections\n\n`buggin` _prepends_ a listener to both the [Process.uncaughtException](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_event_uncaughtexception) and [Process.unhandledRejection](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_event_unhandledrejection) events. If one of these events is emitted _with an `Error` argument_, `buggin` will:\n\n1. Print a notification to `STDERR` and a link to the \"new issue\" page. If the user's terminal supports it, the URL will be displayed as a clickable link, with the requisite querystring hidden; otherwise the entire URL (with query string) will be displayed for the user to copy/paste.\n2. `buggin` disables _all_ of its listeners (including this one).\n3. `buggin` makes a choice:\n   1. If there's no other listener _which was not added by `buggin`_ for the emitted event, the error...\n      1. ...if an uncaught exception, will be _rethrown on the next tick_ out of `buggin`'s listener.\n      2. ...if an unhandled rejection, will be _re-rejected_ from the handler.\n   2. In both above \"pass through\" situations, `buggin` attempts to mimic the default behavior as closely as possible. It _will_ suppress the callsite of its rethrow/rejection, which is unhelpful because ti will point to code in `buggin`. _There may be a way to save this info from the original error?_\n   3. If there _is_ another listener, `buggin` will _not_ rethrow (nor re-reject), and will continue to the next listener as per standard Node.js EE behavior.\n\n### Auto-Configuration\n\n`buggin` attempts to automatically determine the package name and the URL from your package's `package.json`. The logic is kind of gross, but by default, it looks for _closest `package.json` to the main (entry) script_, and pulls the info out.\n\n## Motivation\n\nThis is the _opposite_ of \"This is probably not a problem with npm.\" The fact is, if someone is running your CLI app (and you aren't invoking someone else's code), it _is_ your problem. Wouldn't you like to fix it?\n\nMost users don't bother to report bugs, so maybe this will help!\n\n## Caveats\n\n- This module is _intended_ for use with CLI apps. That said, if you have an idea for better library support, [propose something](https://github.com/boneskull/buggin/issues)!\n- Only a single package can use `buggin` at once. If the [\"main\" module](https://nodejs.org/api/modules.html#modules_require_main) uses `buggin`, it will be preferred over all others; any attempts to use `buggin` after (or before!) the \"main\" module does will be ignored. If the consumer is _not_ the main module, then only _the most recent_ package to call `buggin` \"wins.\"\n- Under normal circumstances, Node.js will exit with code 7 if an uncaught exception is handled and rethrown from the listener. Because `buggin` does not rethrow out of the listener _per se_--and instead rethrows on \"next tick\"--the process will exit with code 1 (as if no such handling occurred).\n- Behavior on unhandled rejection depends on the version of Node.js used. Node.js v12 added a [`--unhandled-rejections-mode` option](https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode), which allows for greater control over whether an unhandled rejection is considered a \"warning\" or a nonzero-exit-code-producing error.\n- `buggin` ignores non-`Error` exceptions or rejections.\n- `buggin` throws stuff in the `global` context (a singleton prop called `buggin` which stores its configuration) to deal with multiple usages more gracefully. Deal with it!\n\n## TODO\n\n- ~~Custom output template~~ **Update:** Added in v0.1.6!\n- Custom issue template (can we reference an existing GitHub issue template?)\n\n## License\n\nLicensed Apache-2.0\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboneskull%2Fbuggin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboneskull%2Fbuggin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboneskull%2Fbuggin/lists"}