{"id":48607840,"url":"https://github.com/bigladder/courier","last_synced_at":"2026-04-09T00:12:41.069Z","repository":{"id":185344737,"uuid":"608746882","full_name":"bigladder/courier","owner":"bigladder","description":"A lightweight, header-only C++ library for use in other libraries that allows client code define how to deliver context-specific error, warning, and informational messages from a library to the client's users, and handle errors from a library when they occur.","archived":false,"fork":false,"pushed_at":"2024-05-27T20:53:03.000Z","size":51,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-05-28T03:05:34.608Z","etag":null,"topics":["error-handling","logging"],"latest_commit_sha":null,"homepage":"","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bigladder.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2023-03-02T16:49:27.000Z","updated_at":"2024-02-02T16:49:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"ee49cec2-1698-449d-b063-ecc05747e5f4","html_url":"https://github.com/bigladder/courier","commit_stats":null,"previous_names":["bigladder/courierr","bigladder/courier"],"tags_count":0,"template":false,"template_full_name":"bigladder/atheneum","purl":"pkg:github/bigladder/courier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigladder%2Fcourier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigladder%2Fcourier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigladder%2Fcourier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigladder%2Fcourier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bigladder","download_url":"https://codeload.github.com/bigladder/courier/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigladder%2Fcourier/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31579144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["error-handling","logging"],"created_at":"2026-04-09T00:12:36.263Z","updated_at":"2026-04-09T00:12:41.064Z","avatar_url":"https://github.com/bigladder.png","language":"CMake","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Courier\n\nA lightweight, header-only C++ library for use in other libraries that allows client code define how to:\n\n1. deliver context-specific error, warning, and informational messages from a library to the client's users, and\n2. handle errors from a library when they occur.\n\nCourier itself is NOT a logger or an error handler. It simply provides a mechanism for clients to decide how to log and\nhandle errors encountered in a library.\n\n## Message Levels\n\nCourier defines four message levels (based\non [Python Logging Levels](https://docs.python.org/3/library/logging.html#logging-levels)):\n\n1. `error`: Due to a more serious problem, the software has not been able to perform some\n   function. Errors encountered in library code imply that execution cannot continue reliably within the library.\n   Courier allows the client to decide how to handle errors. However, if an error is ultimately not handled,\n   Courier will throw an exception from the library.\n2. `warning`: An indication that something unexpected happened, or that a problem might occur\n   in the near future. The software is still working as expected.\n3. `info`: Confirmation that things are working as expected.\n4. `debug`: Detailed information, typically only of interest to a developer trying to\n   diagnose a problem.\n\n## Usage\n\nCourier has two audiences:\n\n1. Library developers that want to give their clients flexibility in message logging and error handling, and\n2. Clients adopting such libraries\n\n### Library Developers\n\nDevelopers add a `Courier` (though we recommend using a `std::shared_ptr\u003cCourier::Courier\u003e`) data member to any\npublic class in a library where an error (or other message event) might occur.\n\n```c++\n#include \u003ccourier/courier.h\u003e\n\nclass LibraryClass {\n  public:\n    LibraryClass(std::string name_in, const std::shared_ptr\u003cCourier::Courier\u003e\u0026 courier_in)\n        : name(std::move(name_in)), courier(courier_in) {}\n  private:\n    std::string name;\n    std::shared_ptr\u003cCourier::Courier\u003e courier;\n};\n```\n\nThe `Courier::Courier` base class defines an interface with a public methods for each of the four message levels:\n\n- `send_debug(const std::string\u0026 message)`\n- `send_info(const std::string\u0026 message)`\n- `send_warning(const std::string\u0026 message)`\n- `send_error(const std::string\u0026 message)`\n\nThese methods are called from within the library class. For example:\n\n```c++\nif (problem_exists)\n{\n    courier-\u003esend_error(\"Something terrible happened.\");\n}\n```\n\n#### Good Practices\n\nThe following examples illustrate ways to use `Courier` most effectively as a library developer. These practices are\nalso implemented in [test/library.h](test/library.h).\n\n1. The parent class should provide access to set and get the `Courier` pointer:\n\n    ```c++\n    void set_courier(std::shared_ptr\u003cCourier::Courier\u003e courier_in) \n    {\n        courier = std::move(courier_in);\n    }\n    std::shared_ptr\u003cCourier::Courier\u003e get_courier() { return courier; }\n   ```\n\n   [helpers.h](include/courier/helpers.h) provides a `Sender` interface class that includes this functionality among\n   other good practices, that can serve as a base class for your library classes.\n\n2. By making `Courier` shared pointers and providing access, multiple closely-related objects can share a\n   single `Courier` instance.\n\n3. Consider defining default derived `Courier`. Some library users will not care how messages are handled, and don't\n   want the additional hassle of developing a derived `Courier` class. An example default `Courier` is provided\n   in [helpers.h](include/courier/helpers.h).\n\n### Library Adopters\n\nAdopters must derive a class from `Courier::Courier`. The `Courier` base class establishes four virtual functions for\nreceiving events:\n\n- `receive_debug(const std::string\u0026 message)`\n- `receive_info(const std::string\u0026 message)`\n- `receive_warning(const std::string\u0026 message)`\n- `receive_error(const std::string\u0026 message)`\n\n#### Good Practices\n\nConsider the following patterns for your derived class(s). These practices are also implemented\nin [test/client.h](test/client.h).\n\n1. Create a function to route all messages into a consistent format.\n\n    ```c++\n    virtual void make_message(const std::string\u0026 message_type, const std::string\u0026 message) = 0;\n    void receive_error(const std::string\u0026 message) override\n    {\n        make_message(\"ERROR\", message);\n        throw std::runtime_error(message);\n    }\n    void receive_warning(const std::string\u0026 message) override { make_message(\"WARNING\", message); }\n    void receive_info(const std::string\u0026 message) override { make_message(\"INFO\", message); }\n    void receive_debug(const std::string\u0026 message) override { make_message(\"DEBUG\", message); }\n    ```\n\n2. Add your context to your received messages:\n\n    ```c++\n    protected:\n       ClientClass* client_class_pointer;\n       void make_message(const std::string\u0026 message_type, const std::string\u0026 message) override\n       {\n           std::string context_format =\n               client_class_pointer ? fmt::format(\" ClientClass '{}':\", client_class_pointer-\u003ename) : \"\";\n           std::cout \u003c\u003c fmt::format(\"[{}]{} {}\", message_type, context_format, message) \u003c\u003c std::endl;\n       }\n   ```\n\n3. Add a message level data member to temporarily silence events below a certain message level.\n\n    ```c++\n    enum class MessageLevel { all, debug, info, warning, error };\n    MessageLevel message_level {MessageLevel::info};\n    void receive_warning(const std::string\u0026 message) override\n    {\n        if (message_level \u003c= MessageLevel::warning) {\n            make_message(\"WARNING\", message);\n        }\n    }\n    ```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigladder%2Fcourier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigladder%2Fcourier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigladder%2Fcourier/lists"}