{"id":19212348,"url":"https://github.com/leafo/lapis-exceptions","last_synced_at":"2026-04-25T23:10:25.262Z","repository":{"id":14605724,"uuid":"17322922","full_name":"leafo/lapis-exceptions","owner":"leafo","description":"Exception tracking for Lapis","archived":false,"fork":false,"pushed_at":"2026-04-25T21:16:12.000Z","size":130,"stargazers_count":16,"open_issues_count":5,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2026-04-25T22:28:38.094Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"MoonScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leafo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2014-03-01T19:53:34.000Z","updated_at":"2026-04-25T21:16:15.000Z","dependencies_parsed_at":"2024-06-19T20:06:10.054Z","dependency_job_id":"f99fb785-1539-4958-ab98-3e88fec09ff6","html_url":"https://github.com/leafo/lapis-exceptions","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/leafo/lapis-exceptions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flapis-exceptions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flapis-exceptions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flapis-exceptions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flapis-exceptions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leafo","download_url":"https://codeload.github.com/leafo/lapis-exceptions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leafo%2Flapis-exceptions/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32279675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-11-09T13:46:39.613Z","updated_at":"2026-04-25T23:10:25.256Z","avatar_url":"https://github.com/leafo.png","language":"MoonScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lapis exception tracker\n\n![test](https://github.com/leafo/lapis-exceptions/workflows/test/badge.svg)\n\nThis module makes the error handler in Lapis save the errors to database.\nOptionally you can make it email you the exceptions.\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAre you updating from before 2.0?\u003c/strong\u003e\u003c/summary\u003e\n\nYou may need to run migrations. Add a new migration to your app and call\n`run_migrations`. It's safe to call it multiple times with no side effects so\nyou're free to add that migration every time you update.\n\n\n```lua\n  [XXX] = require(\"lapis.exceptions.schema\").run_migrations\n```\n\n\u003c/details\u003e\n\n\n## Installing\n\n```bash\n$ luarocks install lapis-exceptions\n```\n\nCreate a new migration that look like this. This will create the necessary\ntables for storing errors, and make any updates to the scchema if necessary. If\nyou are updating the library, you may need to run migrations again. See the\nupgrade details in the release notes.\n\n```lua\n-- migrations.moon/lua\n{\n  ...\n\n  [1439944992]: require(\"lapis.exceptions.schema\").run_migrations\n}\n```\n\nEnable it in your top level app by calling `@enable`. This will wrap your app's\n`handle_error` method with a new function that can record errors, and then call\nthe previous function.\n\n```moon\nclass App extends lapis.Application\n  @enable \"exception_tracking\"\n\n  -- ...\n```\n\nLastly, add to `track_exceptions true` to each environment you want the\nexception tracking to happen, along with any other optional configuration. This\nwill cause the error handler to stard recording errors into the database.\n\n\n```moon\n-- config.moon\nconfig = require \"lapis.config\"\n\nconfig \"production\", -\u003e\n  track_exceptions true\n\n  -- app_name \"My app\" --\u003e optional, gives title to emails\n  -- admin_email \"me@example.com\" --\u003e optional, sends email to you\n  -- ...\n```\n\n## Emails\n\nLapis doesn't have a standardized email sending interface yet, in order for\nmail to work you need to provide your own `send_mail` function.\n\nThe exception mailer will look for a module called `helpers.email` and it\nshould contain a function called `send_email` that takes as arguments the\nrecipient email address, the subject, and the body.\n\n```\n-- this should work to be able to send exception emails:\nrequire(\"helpers.email\").send_email \"leafo@example.com\", \"Hello!\", \"This is an email\"\n```\n\nYou can find an [example send_mail implementation in the MoonRocks\nrepository](https://github.com/leafo/moonrocks-site/blob/master/helpers/email.moon).\n\nAn email will be sent to `config.admin_email` every time a new exception type\nis created, or every time an exception type is updated if it's been 10 minutes\nsince the last update.\n\n## Protected calls\n\nTwo functions are provided for running code with error capturing. Any errors\nthat happen will be captured and written to the exception request table. The\nerror will not propagate outside the call. It works similar to Lua's `pcall`.\n\n\n```moonscript\nimport protected_call from require \"lapis.exceptions\"\n\nsuccess, ret = protected_call -\u003e\n  hello = 3 + \"what\"\n\n```\n\nIf you're running in a Lapis request context, you can pass a request object as\nthe first argument to record any information about that request:\n\n\n```moonscript\nlapis = require \"lapis\"\nimport protected_call from require \"lapis.exceptions\"\n\nclass App extends lapis.Application\n  \"/\": =\u003e\n    success, ret = protected_call @, -\u003e\n      error \"something failed\"\n\n    \"ok\"\n```\n\n\n\n## CLI\n\nA `lapis exceptions` command is provided for managing exceptions from the\nterminal. It must be run from a Lapis project directory with a valid\nconfiguration.\n\n```bash\n# List recent exception groups (default command)\n$ lapis exceptions\n\n# List with filters\n$ lapis exceptions list --status resolved --sort count --since '7 days'\n\n# Search exceptions by message or request path\n$ lapis exceptions list --search \"timeout\" --search-path \"/api/\"\n\n# Show details for a specific exception group\n$ lapis exceptions show 42\n\n# List individual requests for a group\n$ lapis exceptions requests 42 --show-trace\n\n# Update status of exception groups\n$ lapis exceptions update 42 43 --status ignored\n\n# Delete exception groups\n$ lapis exceptions delete 42 43\n\n# Create an exception manually\n$ lapis exceptions create \"something went wrong\" --path \"/test\" --method POST\n```\n\nAll list commands support `--json` for machine-readable output, and `--page`\n/ `--limit` for pagination.\n\n## MCP Server\n\nAn MCP (Model Context Protocol) server is available for integrating exception\nmanagement with AI tools like Claude. Start it over stdio with:\n\n```bash\n$ lapis mcp lapis.exceptions.mcp_server\n```\n\nTo add it to your MCP client configuration (e.g. Claude Desktop or Claude\nCode):\n\n```json\n{\n  \"mcpServers\": {\n    \"lapis-exceptions\": {\n      \"command\": \"lapis\",\n      \"args\": [\"mcp\", \"lapis.exceptions.mcp_server\"],\n      \"cwd\": \"/path/to/your/lapis/project\"\n    }\n  }\n}\n```\n\nThe server provides the following tools:\n\n- `list_exception_groups` -- list and filter exception groups\n- `list_exceptions` -- list individual exception requests\n- `show_exception_group` -- show group details with recent exceptions\n- `create_exception` -- create a new exception\n- `update_exception_group` -- update group status\n- `delete_exception_group` -- delete a group and its exceptions\n\n## Models\n\nTwo models are created to hold exception data: `ExceptionTypes` and\n`ExceptionRequests`. `ExceptionTypes` holds normalized exception messages.\n`ExceptionRequests` holds the original exception message along with data about\nthe request. It has a foreign key pointing to the exception type it belongs to.\n\n\nThe models can be accessed like so:\n\n```moonscript\nimport ExceptionTypes, ExceptionRequests from require \"lapis.exceptions.models\"\n```\n\n## Exception grouping\n\nExceptions are grouped by their exception message in order to reduce the amount\nof top level issues created. A normalized exception message is stored in the\n`ExceptionTypes` table. Numbers and strings are replaced by generic\nidentifiers, line numbers are left alone.\n\nFor example, the following exception message:\n\n    ./lapis/nginx/postgres.lua:51: header part is incomplete: select id from hello_world where name = 'yeah' and age \u003e 10\n\nWould be normalized to:\n\n    ./lapis/nginx/postgres.lua:51: header part is incomplete: select id from hello_world where name = [STRING] and age \u003e [NUMBER]\n\nBefore being stored in the database.\n\n# Changelog\n\n\u003chttps://github.com/leafo/lapis-exceptions/releases\u003e\n\n# Contact\n\nAuthor: Leaf Corcoran (leafo) ([@moonscript](http://twitter.com/moonscript))\nEmail: leafot@gmail.com\nHomepage: \u003chttp://leafo.net\u003e\nLicense: MIT\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleafo%2Flapis-exceptions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleafo%2Flapis-exceptions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleafo%2Flapis-exceptions/lists"}