silk.platform.native.report.
Writes the report of an unhandled error or a trap to a descriptor, with fixed limits.
When to use#
The native and wasm runtimes (silk.platform.native.start, silk.platform.wasi.start,
silk.platform.wasm.start and silk.platform.native.diagnostics) use NativeReport to print
an unhandled error and its call path to standard error, and ErrorForm to print the error's
value after it. Use them in a custom runtime. On wasm32-unknown-unknown, which has no
descriptors, every report goes to the module's report buffer, which the host reads through the
exported silk_report and silk_report_length.
Details#
A report is lines of text:
unhandled error: app.ConfigError
at app/main.silk:12:5
at app.loadEach fragment is written only if it fits in the byte limit. When a limit is reached, the report is incomplete, and later calls write nothing. It does not allocate.
Gotchas#
The report does not close the descriptor.
A write can fail after part of a fragment was written.
A report does not stop a trap or run cleanup.
Examples#
Report an error to standard error#
import silk.platform.native.report { NativeReport }
pub fn main() -> i32 {
// Write to standard error, with at most 512 bytes and 4 caller frames.
let mut report = NativeReport.make(2, 512, 4)
// Each call returns false if the report is incomplete.
let head = run report.unhandled("app.ConfigError", "app/main.silk:12:5")
let load = run report.frame("app.load")
let start = run report.frame("app.main")
if !head || !load || !start || !report.succeeded() {
return 1
}
return 0
}Import as NativeReport with import silk.platform.native.report { NativeReport }.
Public declarations: 2.
NativeReport#
pub struct NativeReportOne report: its descriptor, its remaining byte and frame limits, and whether it is complete.
When to use#
The native and WASI runtimes (silk.platform.native.start, silk.platform.wasi.start and
silk.platform.native.diagnostics) use it to print an unhandled error and its call path to
standard error. Use it in a custom runtime.
Details#
Each fragment is written only if it fits in the byte limit. When a limit is reached, the report is incomplete, and later calls write nothing. It does not allocate.
Gotchas#
The report does not close the descriptor.
A write can fail after part of a fragment was written.
A report does not stop a trap or run cleanup.
Implementation NativeReport#
impl NativeReportAssociated function make#
pub fn make(fd: i32, byteLimit: usize, frameLimit: usize) -> NativeReportReturns a report that writes to fd, with at most byteLimit bytes and frameLimit caller
frames. It does not allocate.
Associated function indented#
pub fn indented(fd: i32, byteLimit: usize, frameLimit: usize, indent: string<'static>) -> NativeReportReturns a report like NativeReport.make that starts each line with indent. The
indent counts toward the byte limit.
When to use#
Use it to nest a report under other output, such as a failed test under the test's name.
Method restart#
pub fn restart(self: &mut Self) -> ()Starts a new report on the same descriptor, with the full byte and frame limits again.
When to use#
Use it when one report writer serves several reports, such as one for each failed test.
Method resume#
pub fn resume(self: &mut Self) -> ()Starts the next part of the same report with the full frame limit again. The byte limit keeps counting, so a report that ran out of bytes stays incomplete.
When to use#
Use it when one report has two lists of frames, such as a trap's caller frames and then the cause the trap happened while handling.
Method unhandled#
pub effect fn unhandled(self: &mut Self, identity: string, source: string) -> boolWrites unhandled error: with identity, then the line at with source. Returns
false if the report is incomplete.
Call it after the runtime has dropped the error value.
Method fatal#
pub effect fn fatal(self: &mut Self, reason: string, source: string) -> boolWrites fatal trap: with reason, then the line at with source. Returns false if
the report is incomplete.
Method frame#
pub effect fn frame(self: &mut Self, label: string) -> boolWrites the line at with the caller label. Returns false if the report is incomplete.
When the frame limit is reached, it writes [trace truncated] one time, and the report
becomes incomplete.
Method truncate#
pub effect fn truncate(self: &mut Self) -> boolWrites [trace truncated], and makes the report incomplete. Later calls write nothing. It
returns false.
Method cause#
pub effect fn cause(self: &mut Self, identity: string, source: string) -> boolWrites while handling: with identity, then the line at with source. Use it for an
earlier error that a handler was handling.
Method succeeded#
pub fn succeeded(self: &Self) -> boolReturns whether all fragments were written within the limits.
ErrorForm#
pub struct ErrorFormThe Debug form of an error, at most 1024 bytes, kept so a runtime can drop the error before
its observer reports it, and print the form after the report.
When to use#
The native and WASI runtimes use it for the unhandled value: line of an unhandled error. Use
it in a custom runtime.
Details#
A longer form is cut at a character boundary and marked as truncated. It does not allocate.
Implementation Writer for ErrorForm#
impl Writer for ErrorFormOperation writeAll#
effect fn writeAll(self: &mut Self, bytes: &[u8]) -> () ! WriterError ? &mut WriterOperation flush#
effect fn flush(self: &mut Self) -> () ! WriterError ? &mut WriterImplementation ErrorForm#
impl ErrorFormAssociated function capture#
pub effect fn capture<E: Debug>(error: &E) -> ErrorFormReturns the Debug form of error, cut to 1024 bytes at a character boundary. A form that
fails to format keeps the part written before the failure.
Method write#
pub effect fn write(self: &Self, fd: i32) -> boolWrites the line unhandled value: with the form to fd, and [value truncated] when the
form was cut. Returns false if a write failed.
Gotchas#
A write can fail after part of the line was written.
Category: Native platform.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, x86_64-unknown-linux-gnu, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.