You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+111-1Lines changed: 111 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -26,7 +26,117 @@ Maven (pom.xml):
26
26
</dependency>
27
27
```
28
28
29
-
## Usage
29
+
To 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:
In 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`.
48
+
49
+
A [BasicDiagnostic](./src/main/java/com/opencastsoftware/yvette/BasicDiagnostic.java) implementation is provided, which can be used to wrap exceptions:
You 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/javase/8/docs/api/java/lang/Appendable.html) instance you wish to use for output, for example [System.out](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#out), [System.err](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#err) or a [StringBuilder](https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html).
56
+
57
+
*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:
There 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.
66
+
67
+
Once you have a [ReportHandler](./src/main/java/com/opencastsoftware/yvette/handlers/ReportHandler.java), it can be used to output diagnostics:
68
+
69
+
```java
70
+
Diagnostic diagnostic =???; // A diagnostic from your application
71
+
reportHandler.display(diagnostic, System.err);
72
+
```
73
+
74
+
## Uncaught exception handler
75
+
76
+
*yvette* provides an implementation of [Thread.UncaughtExceptionHandler](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.UncaughtExceptionHandler.html) which can be used to replace the default handler for all threads.
ReportHandler handler =???; // Your report handler, obtained as described above
82
+
83
+
try {
84
+
UncaughtExceptionHandler.install(handler, System.err); // Installs the new handler
85
+
} finally {
86
+
UncaughtExceptionHandler.uninstall(); // Restores the default handler
87
+
}
88
+
```
89
+
90
+
The setup above will print diagnostics to STDERR:
91
+
92
+
```java
93
+
newThread(() -> {
94
+
Throwable exc =newFileNotFoundException("Couldn't find the file BadFile.java");
95
+
exc.initCause(newAccessDeniedException("Access denied to file BadFile.java"));
96
+
thrownewRuntimeException("Whoops!", exc);
97
+
}).start();
98
+
99
+
/*
100
+
Uncaught exception in thread Thread-5:
101
+
x Whoops!
102
+
|-> Couldn't find the file BadFile.java
103
+
`-> Access denied to file BadFile.java
104
+
105
+
java.lang.RuntimeException: Whoops!
106
+
at com.opencastsoftware.yvette.UncaughtExceptionHandlerTest.lambda$replacesThreadPoolHandler$2(UncaughtExceptionHandlerTest.java:87)
107
+
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
108
+
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
109
+
at java.lang.Thread.run(Thread.java:750)
110
+
Caused by: java.io.FileNotFoundException: Couldn't find the file BadFile.java
111
+
at com.opencastsoftware.yvette.UncaughtExceptionHandlerTest.lambda$replacesThreadPoolHandler$2(UncaughtExceptionHandlerTest.java:85)
112
+
... 3 more
113
+
Caused by: java.nio.file.AccessDeniedException: Access denied to file BadFile.java
114
+
at com.opencastsoftware.yvette.UncaughtExceptionHandlerTest.lambda$replacesThreadPoolHandler$2(UncaughtExceptionHandlerTest.java:86)
115
+
... 3 more
116
+
*/
117
+
```
118
+
119
+
It can also be set as the uncaught exception handler for new threads in a thread pool by using a [ThreadFactory](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadFactory.html):
This is not an exact port of *miette* - there are some differences and unported features:
135
+
136
+
* 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.
137
+
* Only the `GraphicalReportHandler` and `ToStringReportHandler` are currently implemented, there is no `NarratableReportHandler` or `JSONReportHandler` as yet.
138
+
* 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.
139
+
* 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.
0 commit comments