{"id":19329401,"url":"https://github.com/jameswalmsley/ultimate-error-codes","last_synced_at":"2026-06-13T04:32:34.313Z","repository":{"id":145106842,"uuid":"250022386","full_name":"jameswalmsley/ultimate-error-codes","owner":"jameswalmsley","description":"Ultimate Error Code","archived":false,"fork":false,"pushed_at":"2020-03-25T15:51:49.000Z","size":8,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-24T06:45:24.917Z","etag":null,"topics":["c","embedded","error","error-code","error-handling"],"latest_commit_sha":null,"homepage":null,"language":"C","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/jameswalmsley.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}},"created_at":"2020-03-25T15:51:20.000Z","updated_at":"2023-03-15T12:21:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"7dd5833a-1523-4672-b724-832b2409ba51","html_url":"https://github.com/jameswalmsley/ultimate-error-codes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jameswalmsley/ultimate-error-codes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameswalmsley%2Fultimate-error-codes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameswalmsley%2Fultimate-error-codes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameswalmsley%2Fultimate-error-codes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameswalmsley%2Fultimate-error-codes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jameswalmsley","download_url":"https://codeload.github.com/jameswalmsley/ultimate-error-codes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameswalmsley%2Fultimate-error-codes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34272603,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["c","embedded","error","error-code","error-handling"],"created_at":"2024-11-10T02:28:05.144Z","updated_at":"2026-06-13T04:32:34.287Z","avatar_url":"https://github.com/jameswalmsley.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"```\nUltimate Error Codes\n\nCopyright (C) 2013 - 2020 James Walmsley \u003cjames@fullfat-fs.co.uk\u003e\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n```\n\n\n# Ultimate Error Codes\n\nThis system allows an entire system to have a global set of error codes.\nAny level of a system can emit an Error_t and that can be safely passed\nback through to an external user API.\n\nThis ensures that errors are detected and emitted at their source.\n\nIf an Error_t is encountered it should not be discarded and overwritten\nby an Error_t code from a calling function.\n\n* The system can have up to 256 global error codes.\n* The system can have up to 256 modules.\n* Each module can have up to 256 error codes.\n\n* The encoding space is flexible, i.e. lower line resolution for more modules/errors.\n  - 256/256 modules/errors seems reasonable.\n  - Once a project has decided on this split, it should not be changed.\n\nIn abstract an Error is an abstraction of a cause of an event (reason)\ncombined with a unique context (location).\n\nThis encoding scheme combines these properties.\n\n## Use\n\nAll errors are included globally with a simple:\n\n```\n#include \"error.h\"\n```\n\nThe error headers can be easily packaged and deployed for use in other projects,\nallowing them to \"pretty\" print any errorcodes received.\n\n## Error-Code Space\n\n```\n0x80000000  // Top-bit (sign bit) is set - This is an error. (Otherwise a value).\n0x40000000  // Global errors have an extra bit set.\n\n0x0000ff00  // The module the error was emitted from.\n0x000000ff  // The specific error code.\n\n0x0fff0000  // Line number of emitted error.\n0x30000000  // Location resolution bits.\n```\n\n## What errors look like?\n\nA module specific error:\n```\nError   : 0x80070101\nModule  : MODULE_MAIN - main.c:7\nDetails : ERR_NO_MEMORY - Could not allocate memory\n```\n\nA global error.\n```\nError   : 0xc01a0301\nModule  : MODULE_EXAMPLE - example.c:26\nDetails : ERR_GENERIC - Generic error\n```\nErrors should always be printed as a 32-bit hex string.\n\n## Error Location\n\nThe error location is inserted into the error code when the error is emitted\nusing the ERROR() macro.\n\nThe ERROR() macro automatically determines the resolution based on the __LINE__ number.\n\nThe encoding allows for files with lengths up to 61440 lines.\n\n| Resolution | Binning | Range (Begin) | Range (End) |\n| ---------: | ------: | ------------: | ----------: |\n|          0 |       1 |             1 |        4096 |\n|          1 |       2 |          4097 |       12288 |\n|          2 |       4 |         12289 |       28672 |\n|          3 |       8 |         28673 |       61440 |\n\n## Testing For Errors\n\nUse the IS_ERROR() macro:\n\n```\nError_t err = uart_init();\nif(IS_ERROR(err))\n{\n  LOGE(\"Uart initialisation failed\\n\");\n  return err; // Pass the error up!\n}\n```\n\nIts also perfectly fine to do this:\n\n```\nif(err \u003c 0) {}\n```\n\n## Comparing Errors\n\nUse the GET_ERROR() macro to check for a specific error:\n\n```\nError_t mmu_error = init_mmu();\nif(GET_ERROR(mmu_error) == ERR_MMU_INIT_FAILED)\n{\n  /* Fatal error cannot continue.*/\n  printk(\"Kernel could not init mmu.\");\n  for(;;);\n}\n```\n\n## Error Values\n\nI'd recommend keeping values and errors separate, however its perfectly OK to do:\n\n```\nint32_t value = read_adc();\nif(IS_ERROR(value))\n{\n  LOGE(\"Adc read failed\\n\");\n}\n\ncalculateParams(value);\n```\n\nAlternatively:\n\n```\nint32_t value;\nError_t err = read_adc(\u0026value);\nif(IS_ERROR(err))\n{\n  LOGE(\"Adc read failed\\n\");\n}\n\n...\n```\n\n## Error Info and Tables.\n\nThere is a global_errors.h file, to define the global errors:\n\n```\n#ifndef GLOBAL_ERRORS_H\n#define GLOBAL_ERRORS_H\n\n#define DEF_GLOBAL_ERROR(code) (DEF_ERROR(MODULE_GLOBAL, code) | _ERR_GLOBAL_MASK)\n\n#define ERR_NONE                      (0)\n#define ERR_GENERIC   DEF_GLOBAL_ERROR(1)\n#define ERR_INVAL     DEF_GLOBAL_ERROR(2)\n\n#ifdef ERROR_USE_TABLES\nMODULE_ERRORS(MODULE_GLOBAL)\n{\n    DEF_ERR_INFO(ERR_GENERIC, \"Generic error\"),\n    DEF_ERR_INFO(ERR_INVAL,   \"Invalid parameter/value\"),\n};\n#endif\n\n#endif\n```\n\nAll other modules define a list of error codes and their description in the same way.\n\n## Defining Error Codes\n\nSingle prefix for all error codes:\n\n```\nERR_x_y_z\n```\n\nI'd recommend sticking to a convention like:\n\n```\nERR_MYMODULE_CANNOT_COMPUTE // Where MYMODULE namespaces the defines.\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjameswalmsley%2Fultimate-error-codes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjameswalmsley%2Fultimate-error-codes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjameswalmsley%2Fultimate-error-codes/lists"}