{"id":23594205,"url":"https://github.com/opencastsoftware/yvette","last_synced_at":"2025-08-15T17:08:39.113Z","repository":{"id":110159119,"uuid":"592457066","full_name":"opencastsoftware/yvette","owner":"opencastsoftware","description":"A diagnostic reporting library for Java","archived":false,"fork":false,"pushed_at":"2025-06-28T03:38:04.000Z","size":681,"stargazers_count":8,"open_issues_count":5,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-28T04:28:21.727Z","etag":null,"topics":["compilers","diagnostics","error-messages","error-reporting","java","java-library","miette"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/opencastsoftware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2023-01-23T19:17:24.000Z","updated_at":"2025-06-28T03:38:06.000Z","dependencies_parsed_at":"2024-02-23T10:29:37.624Z","dependency_job_id":"f75e6cbf-df88-40e0-83a5-14018172bb43","html_url":"https://github.com/opencastsoftware/yvette","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/opencastsoftware/yvette","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencastsoftware%2Fyvette","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencastsoftware%2Fyvette/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencastsoftware%2Fyvette/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencastsoftware%2Fyvette/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opencastsoftware","download_url":"https://codeload.github.com/opencastsoftware/yvette/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencastsoftware%2Fyvette/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263369558,"owners_count":23456321,"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":["compilers","diagnostics","error-messages","error-reporting","java","java-library","miette"],"created_at":"2024-12-27T09:16:16.799Z","updated_at":"2025-07-03T17:32:32.330Z","avatar_url":"https://github.com/opencastsoftware.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# yvette\n\n[![CI](https://github.com/opencastsoftware/yvette/actions/workflows/ci.yml/badge.svg)](https://github.com/opencastsoftware/yvette/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/opencastsoftware/yvette/branch/main/graph/badge.svg?token=JHVF151VM1)](https://codecov.io/gh/opencastsoftware/yvette)\n[![Maven Central](https://img.shields.io/maven-central/v/com.opencastsoftware/yvette)](https://search.maven.org/search?q=g%3Acom.opencastsoftware+AND+a%3Ayvette)\n[![javadoc](https://javadoc.io/badge2/com.opencastsoftware/yvette/javadoc.svg)](https://javadoc.io/doc/com.opencastsoftware/yvette)\n[![License](https://img.shields.io/github/license/opencastsoftware/yvette?color=blue)](https://spdx.org/licenses/Apache-2.0.html)\n\nA diagnostic reporting library for Java, ported from the Rust library [miette](https://github.com/zkat/miette).\n\n![An example of a graphical error message produced by this library is shown. The error message text is preceded by a red cross symbol. This is followed by the message \"Mismatched type! Expected: Int, Actual: Tree\\[A\\]\". Following the error message a source code snippet is printed, headed by a hyperlink pointing to the underlying file and line number that is in error. Line numbers are shown in the margin indicating the location of the snippet in the underlying source file. The specific term in the source code that is in error is underlined using a blue line.](./images/example-report.png)\n\n## Installation\n\n*yvette* is published for Java 8 and above.\n\nGradle (build.gradle / build.gradle.kts):\n```groovy\nimplementation(\"com.opencastsoftware:yvette:0.2.0\")\n```\n\nMaven (pom.xml):\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.opencastsoftware\u003c/groupId\u003e\n    \u003cartifactId\u003eyvette\u003c/artifactId\u003e\n    \u003cversion\u003e0.2.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nTo use the `GraphicalReportHandler` and other features of the package `com.opencastsoftware.yvette.handlers.graphical`, the [jansi](https://github.com/fusesource/jansi) library is also needed:\n\nGradle (build.gradle / build.gradle.kts):\n```groovy\nimplementation(\"org.fusesource.jansi:jansi:2.4.0\")\n```\n\nMaven (pom.xml):\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.fusesource.jansi\u003c/groupId\u003e\n    \u003cartifactId\u003ejansi\u003c/artifactId\u003e\n    \u003cversion\u003e2.4.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Displaying diagnostics\n\nIn order to display diagnostics with *yvette*, your application's error messages must implement the abstract class [Diagnostic](./src/main/java/com/opencastsoftware/yvette/Diagnostic.java). All of the methods of this class may return `null`, but bear in mind that your diagnostics may not be very helpful without a `message`.\n\nA [BasicDiagnostic](./src/main/java/com/opencastsoftware/yvette/BasicDiagnostic.java) implementation is provided, which can be used to wrap exceptions:\n\n```java\nDiagnostic err = new BasicDiagnostic(e.getMessage(), e.getCause());\n```\n\nYou can then implement a [ReportHandler](./src/main/java/com/opencastsoftware/yvette/handlers/ReportHandler.java) to display your diagnostics using the [Appendable](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Appendable.html) instance you wish to use for output, for example [System.out](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/System.html#out), [System.err](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/System.html#err) or a [StringBuilder](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/StringBuilder.html).\n\n*yvette* provides a [GraphicalReportHandler](./src/main/java/com/opencastsoftware/yvette/handlers/graphical/GraphicalReportHandler.java) which produces output like the screenshot above. You can create one of these using the `GraphicalReportHandler.builder()` static method:\n\n```java\nReportHandler reportHandler = GraphicalReportHandler.builder()\n    .withRgbColours(RgbColours.PREFERRED)\n    .buildFor(System.err);\n```\n\nThere are some terminal feature detection features in *yvette*. If you wish to bypass these, use the `withColours`, `withTerminalWidth` and `withUnicode` methods of the builder to enable or disable those features explicitly. However, please bear in mind that using `withColours` to force enable colour output will override the [NO_COLOR](https://no-color.org/) detection implemented by this library.\n\nOnce you have a [ReportHandler](./src/main/java/com/opencastsoftware/yvette/handlers/ReportHandler.java), it can be used to output diagnostics:\n\n```java\nDiagnostic diagnostic = ???; // A diagnostic from your application\nreportHandler.display(diagnostic, System.err);\n```\n\n## Uncaught exception handler\n\n*yvette* provides an implementation of [Thread.UncaughtExceptionHandler](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.UncaughtExceptionHandler.html) which can be used to replace the default handler for all threads.\n\n```java\nimport com.opencastsoftware.yvette.UncaughtExceptionHandler;\n\nReportHandler handler = ???; // Your report handler, obtained as described above\n\ntry {\n    UncaughtExceptionHandler.install(handler, System.err); // Installs the new handler\n} finally {\n    UncaughtExceptionHandler.uninstall(); // Restores the default handler\n}\n```\n\nThe setup above will print diagnostics to STDERR:\n\n```java\nnew Thread(() -\u003e {\n    Throwable exc = new FileNotFoundException(\"Couldn't find the file BadFile.java\");\n    exc.initCause(new AccessDeniedException(\"Access denied to file BadFile.java\"));\n    throw new RuntimeException(\"Whoops!\", exc);\n}).start();\n\n/*\nUncaught exception in thread Thread-5:\n    x Whoops!\n    |-\u003e Couldn't find the file BadFile.java\n    `-\u003e Access denied to file BadFile.java\n\njava.lang.RuntimeException: Whoops!\n    at com.opencastsoftware.yvette.UncaughtExceptionHandlerTest.lambda$replacesThreadPoolHandler$2(UncaughtExceptionHandlerTest.java:87)\n    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n    at java.lang.Thread.run(Thread.java:750)\nCaused by: java.io.FileNotFoundException: Couldn't find the file BadFile.java\n    at com.opencastsoftware.yvette.UncaughtExceptionHandlerTest.lambda$replacesThreadPoolHandler$2(UncaughtExceptionHandlerTest.java:85)\n    ... 3 more\nCaused by: java.nio.file.AccessDeniedException: Access denied to file BadFile.java\n    at com.opencastsoftware.yvette.UncaughtExceptionHandlerTest.lambda$replacesThreadPoolHandler$2(UncaughtExceptionHandlerTest.java:86)\n    ... 3 more\n*/\n```\n\nIt can also be set as the uncaught exception handler for new threads in a thread pool by using a [ThreadFactory](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ThreadFactory.html):\n\n```java\nThread.UncaughtExceptionHandler excHandler = UncaughtExceptionHandler.create(handler, System.err);\n\nThreadFactory threadFactory = runnable -\u003e {\n    Thread thread = new Thread(runnable);\n    thread.setUncaughtExceptionHandler(excHandler);\n    thread.setDaemon(true);\n    return newThread;\n};\n```\n\n## Deviations and Limitations\n\nThis is not an exact port of *miette* - there are some differences and unported features:\n\n* Where *miette* and the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/)'s definitions deviate, we have erred on the side of alignment with LSP. This is for ease of integrating *yvette* with language server applications. For example, *miette* uses `SourceSpan` to keep track of the byte offset and length of a span within a source file. However, *yvette*'s equivalent of `SourceSpan` is called `Range`, and specifies a start and end `Position`, each of which refers to a zero-indexed line and character position within a document. The upside of this is alignment with LSP, but the downside is that we can no longer efficiently read arbitrary offsets of a source file in order to get the span contents.\n* Only the `GraphicalReportHandler` and `ToStringReportHandler` are currently implemented, there is no `NarratableReportHandler` or `JSONReportHandler` as yet.\n* There is no special handling of tab characters or [unicode character width](https://crates.io/crates/unicode-width) in *yvette* yet, which may mean that your highlights are misaligned with the source code they are supposed to underline.\n* Related diagnostics are not currently implemented in *yvette*, since the definition of `DiagnosticRelatedInformation` is sufficiently different in the Language Server Protocol that we haven't decided how to implement it yet.\n\n## Acknowlegements\n\nThis project wouldn't exist without the work of [zkat](https://github.com/zkat) and the other miette contributors.\n\n## License\n\nAll code in this repository is licensed under the Apache License, Version 2.0. See [LICENSE](./LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopencastsoftware%2Fyvette","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopencastsoftware%2Fyvette","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopencastsoftware%2Fyvette/lists"}