refactor(errors): adopt reportable error terminology
This commit is contained in:
1 parent
21e9497915
commit
9fec2fa095
92 files changed
+270
-269
No files matched your search
@@ -80,16 +80,16 @@ The build watches every fragment and generates one `message::kaptan` module;
|
|||||||
fragments are never separately generated Rust modules. `kaptan-log` itself has
|
fragments are never separately generated Rust modules. `kaptan-log` itself has
|
||||||
no MAVLink, platform, time, allocation, or filesystem dependency; its sole
|
no MAVLink, platform, time, allocation, or filesystem dependency; its sole
|
||||||
configuration coupling is compile-time enum metadata for `LevelFilter`.
|
configuration coupling is compile-time enum metadata for `LevelFilter`.
|
||||||
`kaptan-err-propagate` independently owns explicitly assigned typed-error identity,
|
`kaptan-err-reportable` independently owns explicitly assigned reportable-error
|
||||||
function-boundary propagation, and a bounded nonblocking ingress; it has
|
identity and a bounded nonblocking ingress; it has
|
||||||
no logging, MAVLink, platform, filesystem, or clock dependency. Event creation
|
no logging, MAVLink, platform, filesystem, or clock dependency. Event creation
|
||||||
is independent from sink filtering, allowing a future blackbox and MAVLink to
|
is independent from sink filtering, allowing a future blackbox and MAVLink to
|
||||||
select different policies. The platform drains typed errors before its bounded
|
select different policies. The platform drains reportable errors before its bounded
|
||||||
critical and best-effort log queues and removes a pending record only after TX
|
critical and best-effort log queues and removes a pending record only after TX
|
||||||
admission. `KAPTAN_LOG` carries one conventional level plus one bounded text
|
admission. `KAPTAN_LOG` carries one conventional level plus one bounded text
|
||||||
field; `KAPTAN_ERROR` carries an explicitly assigned 16-bit ID and the bounded
|
field; `KAPTAN_ERROR` carries an explicitly assigned 16-bit ID and the bounded
|
||||||
`file:line` of the reporting boundary. Its
|
`file:line` of the reporting point. Its
|
||||||
message kind already identifies a typed firmware error. Heartbeat and safety
|
message kind already identifies a reportable firmware error. Heartbeat and safety
|
||||||
telemetry remain separate from diagnostics.
|
telemetry remain separate from diagnostics.
|
||||||
|
|
||||||
See [Configuration](configuration.md) for the deployment matrix and GCS transaction
|
See [Configuration](configuration.md) for the deployment matrix and GCS transaction
|
||||||
|
|||||||
+19
-19
@@ -1,9 +1,9 @@
|
|||||||
# Errors
|
# Errors
|
||||||
|
|
||||||
Public Kaptan error enums derive the pure `KaptanError` implementation:
|
Public reportable Kaptan error enums derive `KaptanError`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#[derive(Debug, kaptan_err_propagate::KaptanError)]
|
#[derive(Debug, kaptan_err_reportable::KaptanError)]
|
||||||
enum SensorError {
|
enum SensorError {
|
||||||
#[kaptan_error(id = 12345)]
|
#[kaptan_error(id = 12345)]
|
||||||
TransferFault,
|
TransferFault,
|
||||||
@@ -11,14 +11,14 @@ enum SensorError {
|
|||||||
UnexpectedIdentity(u8),
|
UnexpectedIdentity(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn service_sensor() -> Result<(), SensorError> {
|
fn service_sensor() -> Result<(), SensorError> {
|
||||||
read_sensor()?;
|
read_sensor()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The derive implements `core::error::Error`, `Display`, and `ErrorReport`. It
|
The derive implements `core::error::Error`, `Display`, and `ReportableError`. It
|
||||||
requires a nonzero explicit ID on every variant and retains no type, variant,
|
requires a nonzero explicit ID on every variant and retains no type, variant,
|
||||||
or module string. `Display` renders the decimal ID. Renaming, moving, or
|
or module string. `Display` renders the decimal ID. Renaming, moving, or
|
||||||
reordering a Rust variant therefore does not change its receiver contract.
|
reordering a Rust variant therefore does not change its receiver contract.
|
||||||
@@ -26,11 +26,11 @@ Missing and same-enum duplicate IDs are rejected by the derive. Reusing an ID
|
|||||||
across error enums generates the same reserved linker symbol and fails the
|
across error enums generates the same reserved linker symbol and fails the
|
||||||
final firmware build.
|
final firmware build.
|
||||||
|
|
||||||
`#[kaptan_err_propagate::propagate]` observes the ordinary `Result` produced
|
`#[kaptan_err_reportable::propagate]` turns an annotated function into a
|
||||||
by one terminal diagnostic boundary. If an `Err` leaves that function, the attribute
|
reporting point. If a reportable `Err` leaves that function, the attribute makes
|
||||||
makes one nonblocking admission attempt and returns the exact same `Err` to the
|
one nonblocking admission attempt and returns the exact same `Err` to the
|
||||||
caller. The record contains the final converted error ID and the compile-time
|
caller. The record contains the final converted error ID and the compile-time
|
||||||
`file:line` of that annotated boundary. This is where the `Err` enters
|
`file:line` of that reporting point. This is where the `Err` enters
|
||||||
diagnostics, not necessarily the line where a deeper callee originally
|
diagnostics, not necessarily the line where a deeper callee originally
|
||||||
constructed it. `?`, explicit returns, result aliases, and `From` conversion
|
constructed it. `?`, explicit returns, result aliases, and `From` conversion
|
||||||
retain their normal Rust behavior. An error handled inside the function is
|
retain their normal Rust behavior. An error handled inside the function is
|
||||||
@@ -46,35 +46,35 @@ renaming, moving, or reordering an existing variant keeps its assigned ID.
|
|||||||
The example numbers above are illustrative and must be replaced with
|
The example numbers above are illustrative and must be replaced with
|
||||||
unallocated catalog values when used in production code.
|
unallocated catalog values when used in production code.
|
||||||
|
|
||||||
Only the terminal boundary is annotated. If nested functions are both
|
Only the intended reporting point is annotated. If nested functions are both
|
||||||
annotated, each boundary makes its own report attempt; the ingress does not
|
annotated, each function makes its own report attempt; the ingress does not
|
||||||
mark or mutate error values to deduplicate them. Expected validation,
|
mark or mutate error values to deduplicate them. Expected validation,
|
||||||
backpressure, retry, and untrusted-input results remain unannotated. In
|
backpressure, retry, and untrusted-input results remain unannotated. In
|
||||||
particular, transient SPI/I²C `Busy` and unavailable range measurements stay
|
particular, transient SPI/I²C `Busy` and unavailable range measurements stay
|
||||||
inside their service retry/idle paths. In contrast, every logging
|
inside their service retry/idle paths. In contrast, every logging
|
||||||
macro—including `kaptan_log::error!`—produces only
|
macro—including `kaptan_log::error!`—produces only
|
||||||
`KAPTAN_LOG`. Error propagation is not a replacement for safety state,
|
`KAPTAN_LOG`. Error reporting is not a replacement for safety state,
|
||||||
actuator inhibit, or typed configuration results.
|
actuator inhibit, or typed configuration results.
|
||||||
|
|
||||||
`kaptan-err-propagate` owns error identity and its independent one-slot
|
`kaptan-err-reportable` owns reportable-error identity and its independent
|
||||||
ingress. A pending record contains only the compact ID and a static reference
|
one-slot ingress. A pending record contains only the compact ID and a static
|
||||||
to the propagation boundary's `file:line`. The MAVLink adapter copies that
|
reference to the reporting point's `file:line`. The MAVLink adapter copies that
|
||||||
location into its fixed field when constructing `KAPTAN_ERROR`. Producers never
|
location into its fixed field when constructing `KAPTAN_ERROR`. Producers never
|
||||||
encode or transmit MAVLink themselves. Admission is bounded and lossy if a
|
encode or transmit MAVLink themselves. Admission is bounded and lossy if a
|
||||||
different typed error is already pending.
|
different reportable error is already pending.
|
||||||
|
|
||||||
## What the receiver sees
|
## What the receiver sees
|
||||||
|
|
||||||
- Configuration writes receive authoritative structured failures through
|
- Configuration writes receive authoritative structured failures through
|
||||||
`KAPTAN_CONFIG_RESULT`: operation, lifecycle state, field IDs, validation
|
`KAPTAN_CONFIG_RESULT`: operation, lifecycle state, field IDs, validation
|
||||||
rule, and protocol error code. A terminal persistence failure also reports
|
rule, and protocol error code. A reportable persistence failure also emits
|
||||||
the storage-only `CommitTransactionError::Store` boundary once as
|
the storage-only `CommitTransactionError::Store` ID once as
|
||||||
`KAPTAN_ERROR`; replaying the cached command result does not repeat the error
|
`KAPTAN_ERROR`; replaying the cached command result does not repeat the error
|
||||||
or the flash operation.
|
or the flash operation.
|
||||||
- Terminal typed `ErrorReport` faults reach the F722 MAVLink worker as a
|
- Reported `ReportableError` values reach the F722 MAVLink worker as a
|
||||||
`KAPTAN_ERROR`, subject to bounded transport admission. The payload is
|
`KAPTAN_ERROR`, subject to bounded transport admission. The payload is
|
||||||
`{ error_id, raised_at[96] }`. `raised_at` is a zero-padded UTF-8
|
`{ error_id, raised_at[96] }`. `raised_at` is a zero-padded UTF-8
|
||||||
`file:line` prefix for the annotated propagation boundary.
|
`file:line` prefix for the reporting point.
|
||||||
The message kind itself identifies an error; no level is duplicated in the
|
The message kind itself identifies an error; no level is duplicated in the
|
||||||
payload. Dynamic human-readable context belongs in `KAPTAN_LOG`, while
|
payload. Dynamic human-readable context belongs in `KAPTAN_LOG`, while
|
||||||
structured protocol failures remain in their owning response message.
|
structured protocol failures remain in their owning response message.
|
||||||
|
|||||||
+9
-9
@@ -11,18 +11,18 @@ kaptan_log::trace!("prediction step complete");
|
|||||||
```
|
```
|
||||||
|
|
||||||
All five macros emit `KAPTAN_LOG`; their level never selects a different wire
|
All five macros emit `KAPTAN_LOG`; their level never selects a different wire
|
||||||
message. When a terminal typed firmware error escapes a reviewed
|
message. When a reportable firmware error escapes a reviewed
|
||||||
`#[kaptan_err_propagate::propagate]` function, it makes one bounded admission attempt
|
`#[kaptan_err_reportable::propagate]` function, it makes one bounded admission attempt
|
||||||
to the separate `KAPTAN_ERROR` ingress.
|
to the separate `KAPTAN_ERROR` ingress.
|
||||||
|
|
||||||
`kaptan-log` formats each event once into a fixed bounded buffer and never
|
`kaptan-log` formats each event once into a fixed bounded buffer and never
|
||||||
sends MAVLink, allocates, blocks, changes flight state, or touches DMA. The
|
sends MAVLink, allocates, blocks, changes flight state, or touches DMA. The
|
||||||
composition fans the event into each enabled sink; the sole MAVLink worker
|
composition fans the event into each enabled sink; the sole MAVLink worker
|
||||||
drains its bounded sink queue. Ordinary log text uses one 160-byte bounded
|
drains its bounded sink queue. Ordinary log text uses one 160-byte bounded
|
||||||
record. Typed-error records contain the explicit ID and a static reference to
|
record. Reportable-error records contain the explicit ID and a static reference
|
||||||
the annotated propagation boundary until the MAVLink adapter copies its
|
to the reporting point until the MAVLink adapter copies its
|
||||||
`file:line` into the 96-byte `raised_at` field.
|
`file:line` into the 96-byte `raised_at` field.
|
||||||
Logs and typed errors use independent fixed atomic
|
Logs and reportable errors use independent fixed atomic
|
||||||
ingresses; interrupt and worker producers make one nonblocking admission
|
ingresses; interrupt and worker producers make one nonblocking admission
|
||||||
attempt, and only the MAVLink worker encodes or transmits a retained event.
|
attempt, and only the MAVLink worker encodes or transmits a retained event.
|
||||||
Panic and hard-fault paths still do not attempt live telemetry.
|
Panic and hard-fault paths still do not attempt live telemetry.
|
||||||
@@ -30,7 +30,7 @@ Panic and hard-fault paths still do not attempt live telemetry.
|
|||||||
## Receiver contract
|
## Receiver contract
|
||||||
|
|
||||||
`definitions/kaptan/log.xml` and `definitions/kaptan/error.xml` separate
|
`definitions/kaptan/log.xml` and `definitions/kaptan/error.xml` separate
|
||||||
ordinary logs and typed errors:
|
ordinary logs and reportable errors:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
KAPTAN_LOG { level, flags, message_length, message[160] }
|
KAPTAN_LOG { level, flags, message_length, message[160] }
|
||||||
@@ -46,12 +46,12 @@ or the complete field when no zero is present.
|
|||||||
`KAPTAN_LOG.level` accepts only Error (3), Warning (4), Info (6), and Debug
|
`KAPTAN_LOG.level` accepts only Error (3), Warning (4), Info (6), and Debug
|
||||||
(7); Trace is encoded as Debug (7) plus the `TRACE` flag. Other MAVLink
|
(7); Trace is encoded as Debug (7) plus the `TRACE` flag. Other MAVLink
|
||||||
severity numbers are not Kaptan log levels.
|
severity numbers are not Kaptan log levels.
|
||||||
The `KAPTAN_ERROR` message kind already means a typed firmware error, so it has
|
The `KAPTAN_ERROR` message kind already means a reportable firmware error, so it has
|
||||||
no redundant level or flags field.
|
no redundant level or flags field.
|
||||||
|
|
||||||
`error_id` is the stable nonzero catalog number explicitly assigned to the
|
`error_id` is the stable nonzero catalog number explicitly assigned to the
|
||||||
Rust error variant. Renaming or reordering a variant does not change it.
|
Rust error variant. Renaming or reordering a variant does not change it.
|
||||||
`raised_at` identifies the annotated boundary where the `Err` entered
|
`raised_at` identifies the reporting point where the `Err` entered
|
||||||
diagnostics. Error details requiring
|
diagnostics. Error details requiring
|
||||||
machine action stay in their owning protocol, notably `KAPTAN_CONFIG_RESULT`.
|
machine action stay in their owning protocol, notably `KAPTAN_CONFIG_RESULT`.
|
||||||
Delivery is bounded and lossy under link pressure; heartbeat and safety
|
Delivery is bounded and lossy under link pressure; heartbeat and safety
|
||||||
@@ -65,7 +65,7 @@ event.
|
|||||||
The single restart-only `mavlink.logging.level_filter` field uses the familiar
|
The single restart-only `mavlink.logging.level_filter` field uses the familiar
|
||||||
Off, Error, Warn, Info, Debug, and Trace choices. `Info`, for example, accepts
|
Off, Error, Warn, Info, Debug, and Trace choices. `Info`, for example, accepts
|
||||||
Error, Warn, and Info log events. `Off` suppresses `KAPTAN_LOG` on MAVLink
|
Error, Warn, and Info log events. `Off` suppresses `KAPTAN_LOG` on MAVLink
|
||||||
without suppressing typed `KAPTAN_ERROR` reports or events sent to another
|
without suppressing reportable `KAPTAN_ERROR` events or logs sent to another
|
||||||
sink. There is no separate enable flag and no MAVLink-specific set of extra
|
sink. There is no separate enable flag and no MAVLink-specific set of extra
|
||||||
runtime log levels. F722 uses the validated filter recovered at boot, falling
|
runtime log levels. F722 uses the validated filter recovered at boot, falling
|
||||||
back to its board factory when the journal is empty or invalid.
|
back to its board factory when the journal is empty or invalid.
|
||||||
|
|||||||
+2
-2
@@ -50,8 +50,8 @@ log history.
|
|||||||
The custom Kaptan definitions are aggregated by `definitions/kaptan.xml` from
|
The custom Kaptan definitions are aggregated by `definitions/kaptan.xml` from
|
||||||
`kaptan/config.xml`, `kaptan/log.xml`, and `kaptan/error.xml`.
|
`kaptan/config.xml`, `kaptan/log.xml`, and `kaptan/error.xml`.
|
||||||
`KAPTAN_LOG` is an outbound human-readable four-field record. `KAPTAN_ERROR`
|
`KAPTAN_LOG` is an outbound human-readable four-field record. `KAPTAN_ERROR`
|
||||||
is the separate bounded channel for typed firmware errors, carrying a stable
|
is the separate bounded channel for reportable firmware errors, carrying a
|
||||||
explicit ID plus the `file:line` of its propagation boundary, and needs no
|
stable explicit ID plus the `file:line` of its reporting point, and needs no
|
||||||
redundant level field. Configuration messages back the current target-described
|
redundant level field. Configuration messages back the current target-described
|
||||||
web configurator and the future signed GCS. See
|
web configurator and the future signed GCS. See
|
||||||
[Configuration](configuration.md), [Logs](logs.md), and [Errors](errors.md) for
|
[Configuration](configuration.md), [Logs](logs.md), and [Errors](errors.md) for
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ This page collects stable limits and points to the detailed contracts.
|
|||||||
| F722 persistence | One bounded fixed scalar snapshot inside each slot of a power-loss-safe two-slot flash journal. |
|
| F722 persistence | One bounded fixed scalar snapshot inside each slot of a power-loss-safe two-slot flash journal. |
|
||||||
| Config transaction | One owner-bound RAM transaction with typed scalar writes; commit is restart-required. |
|
| Config transaction | One owner-bound RAM transaction with typed scalar writes; commit is restart-required. |
|
||||||
| Config discovery | Correlated `KAPTAN_CONFIG_INFO_REQUEST` / `KAPTAN_CONFIG_INFO`, then exact-index descriptor/enum-option and field-value requests. |
|
| Config discovery | Correlated `KAPTAN_CONFIG_INFO_REQUEST` / `KAPTAN_CONFIG_INFO`, then exact-index descriptor/enum-option and field-value requests. |
|
||||||
| Diagnostics | `KAPTAN_LOG` (51020) for macro-produced level/text; `KAPTAN_ERROR` (51021) for a bounded typed `{ error_id, raised_at[96] }` firmware error. |
|
| Diagnostics | `KAPTAN_LOG` (51020) for macro-produced level/text; `KAPTAN_ERROR` (51021) for a bounded reportable `{ error_id, raised_at[96] }` firmware error. |
|
||||||
| F722 configuration | Target-described fields and board factory defaults; the current local transport is a directly wired unsigned UART with motor outputs physically inhibited. |
|
| F722 configuration | Target-described fields and board factory defaults; the current local transport is a directly wired unsigned UART with motor outputs physically inhibited. |
|
||||||
|
|
||||||
Read [Configuration](configuration.md) for the field/consumer matrix and GCS
|
Read [Configuration](configuration.md) for the field/consumer matrix and GCS
|
||||||
transaction sequence, [Logs](logs.md) for receiver decoding and filtering, and
|
transaction sequence, [Logs](logs.md) for receiver decoding and filtering, and
|
||||||
[Errors](errors.md) for error propagation and panic scope.
|
[Errors](errors.md) for reportable errors and panic scope.
|
||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
|
|||||||
Generated
+16
-16
@@ -156,7 +156,7 @@ name = "kaptan-config"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-config-derive",
|
"kaptan-config-derive",
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-log",
|
"kaptan-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ name = "kaptan-config-mavlink"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-config",
|
"kaptan-config",
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-mavlink",
|
"kaptan-mavlink",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ dependencies = [
|
|||||||
name = "kaptan-control"
|
name = "kaptan-control"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-math",
|
"kaptan-math",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ name = "kaptan-data-channel"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-dma",
|
"kaptan-dma",
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-mavlink",
|
"kaptan-mavlink",
|
||||||
"kaptan-sensor",
|
"kaptan-sensor",
|
||||||
"kaptan-time",
|
"kaptan-time",
|
||||||
@@ -217,7 +217,7 @@ dependencies = [
|
|||||||
name = "kaptan-diagnostics-mavlink"
|
name = "kaptan-diagnostics-mavlink"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-log",
|
"kaptan-log",
|
||||||
"kaptan-mavlink",
|
"kaptan-mavlink",
|
||||||
"mavlink",
|
"mavlink",
|
||||||
@@ -231,7 +231,7 @@ version = "0.1.0"
|
|||||||
name = "kaptan-drivers"
|
name = "kaptan-drivers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-i2c",
|
"kaptan-i2c",
|
||||||
"kaptan-sensor",
|
"kaptan-sensor",
|
||||||
"kaptan-spi",
|
"kaptan-spi",
|
||||||
@@ -239,14 +239,14 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kaptan-err-propagate"
|
name = "kaptan-err-reportable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-err-propagate-macros",
|
"kaptan-err-reportable-macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kaptan-err-propagate-macros"
|
name = "kaptan-err-reportable-macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -260,7 +260,7 @@ name = "kaptan-flight-config"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-config",
|
"kaptan-config",
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-log",
|
"kaptan-log",
|
||||||
"minicbor",
|
"minicbor",
|
||||||
]
|
]
|
||||||
@@ -307,7 +307,7 @@ dependencies = [
|
|||||||
name = "kaptan-math"
|
name = "kaptan-math"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -316,7 +316,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"kaptan-dma",
|
"kaptan-dma",
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-sensor",
|
"kaptan-sensor",
|
||||||
"kaptan-time",
|
"kaptan-time",
|
||||||
"kaptan-tx",
|
"kaptan-tx",
|
||||||
@@ -331,7 +331,7 @@ dependencies = [
|
|||||||
name = "kaptan-navigation"
|
name = "kaptan-navigation"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-math",
|
"kaptan-math",
|
||||||
"kaptan-sensor",
|
"kaptan-sensor",
|
||||||
"kaptan-time",
|
"kaptan-time",
|
||||||
@@ -341,7 +341,7 @@ dependencies = [
|
|||||||
name = "kaptan-safety"
|
name = "kaptan-safety"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-time",
|
"kaptan-time",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -360,7 +360,7 @@ dependencies = [
|
|||||||
"kaptan-config-mavlink",
|
"kaptan-config-mavlink",
|
||||||
"kaptan-control",
|
"kaptan-control",
|
||||||
"kaptan-diagnostics-mavlink",
|
"kaptan-diagnostics-mavlink",
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-flight-config",
|
"kaptan-flight-config",
|
||||||
"kaptan-flight-runtime",
|
"kaptan-flight-runtime",
|
||||||
"kaptan-log",
|
"kaptan-log",
|
||||||
@@ -509,7 +509,7 @@ dependencies = [
|
|||||||
"kaptan-diagnostics-mavlink",
|
"kaptan-diagnostics-mavlink",
|
||||||
"kaptan-dma",
|
"kaptan-dma",
|
||||||
"kaptan-drivers",
|
"kaptan-drivers",
|
||||||
"kaptan-err-propagate",
|
"kaptan-err-reportable",
|
||||||
"kaptan-i2c",
|
"kaptan-i2c",
|
||||||
"kaptan-log",
|
"kaptan-log",
|
||||||
"kaptan-mavlink",
|
"kaptan-mavlink",
|
||||||
|
|||||||
+2
-2
@@ -10,8 +10,8 @@ members = [
|
|||||||
"libs/kaptan-data-channel",
|
"libs/kaptan-data-channel",
|
||||||
"libs/kaptan-dma",
|
"libs/kaptan-dma",
|
||||||
"libs/kaptan-drivers",
|
"libs/kaptan-drivers",
|
||||||
"libs/kaptan-err-propagate",
|
"libs/kaptan-err-reportable",
|
||||||
"libs/kaptan-err-propagate-macros",
|
"libs/kaptan-err-reportable-macros",
|
||||||
"libs/kaptan-flight-config",
|
"libs/kaptan-flight-config",
|
||||||
"libs/kaptan-flight-runtime",
|
"libs/kaptan-flight-runtime",
|
||||||
"libs/kaptan-i2c",
|
"libs/kaptan-i2c",
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-config = { path = "../kaptan-config" }
|
kaptan-config = { path = "../kaptan-config" }
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-mavlink = { path = "../kaptan-mavlink", default-features = false, features = ["dialect-kaptan"] }
|
kaptan-mavlink = { path = "../kaptan-mavlink", default-features = false, features = ["dialect-kaptan"] }
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//! Stable typed outcomes for the Kaptan configuration microservice.
|
//! Stable typed outcomes for the Kaptan configuration microservice.
|
||||||
|
|
||||||
use kaptan_config::{ConfigState, ConfigViolation, FieldId};
|
use kaptan_config::{ConfigState, ConfigViolation, FieldId};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
/// Operation reported in an authoritative result record.
|
/// Operation reported in an authoritative result record.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub(super) struct Session {
|
|||||||
pub(super) revision: u32,
|
pub(super) revision: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, kaptan_err_propagate::KaptanError)]
|
#[derive(Debug, kaptan_err_reportable::KaptanError)]
|
||||||
enum CommitTransactionError<E> {
|
enum CommitTransactionError<E> {
|
||||||
#[kaptan_error(id = 2201)]
|
#[kaptan_error(id = 2201)]
|
||||||
Store(E),
|
Store(E),
|
||||||
@@ -337,9 +337,9 @@ impl ConfigProtocol {
|
|||||||
|
|
||||||
/// Classifies expected configuration rejection separately from a terminal
|
/// Classifies expected configuration rejection separately from a terminal
|
||||||
/// persistence failure. Only the latter leaves this boundary and becomes
|
/// persistence failure. Only the latter leaves this boundary and becomes
|
||||||
/// a typed firmware error; the configuration result remains authoritative
|
/// a reportable firmware error; the configuration result remains authoritative
|
||||||
/// for the requesting user.
|
/// for the requesting user.
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn commit_transaction<C, S>(
|
fn commit_transaction<C, S>(
|
||||||
&mut self,
|
&mut self,
|
||||||
manager: &mut ConfigManager<C, S>,
|
manager: &mut ConfigManager<C, S>,
|
||||||
@@ -1235,7 +1235,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failed_commit_reports_the_returned_error_only_once() {
|
fn failed_commit_reports_the_returned_error_only_once() {
|
||||||
while kaptan_err_propagate::take().is_some() {}
|
while kaptan_err_reportable::take().is_some() {}
|
||||||
let persists = Rc::new(Cell::new(0));
|
let persists = Rc::new(Cell::new(0));
|
||||||
let store = FailingStore(Rc::clone(&persists));
|
let store = FailingStore(Rc::clone(&persists));
|
||||||
let mut manager = ConfigManager::new(Candidate(2), (), store).unwrap();
|
let mut manager = ConfigManager::new(Candidate(2), (), store).unwrap();
|
||||||
@@ -1277,9 +1277,9 @@ mod tests {
|
|||||||
Some(ProtocolError::StorageFailure)
|
Some(ProtocolError::StorageFailure)
|
||||||
);
|
);
|
||||||
let error =
|
let error =
|
||||||
kaptan_err_propagate::take().expect("failed commit must report its returned error");
|
kaptan_err_reportable::take().expect("failed commit must report its returned error");
|
||||||
assert_eq!(error.id(), 2201);
|
assert_eq!(error.id(), 2201);
|
||||||
while kaptan_err_propagate::take().is_some() {}
|
while kaptan_err_reportable::take().is_some() {}
|
||||||
|
|
||||||
protocol
|
protocol
|
||||||
.dispatch(&mut manager, Authorized::host(7, commit), |_| {
|
.dispatch(&mut manager, Authorized::host(7, commit), |_| {
|
||||||
@@ -1288,7 +1288,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(persists.get(), 1);
|
assert_eq!(persists.get(), 1);
|
||||||
assert!(
|
assert!(
|
||||||
kaptan_err_propagate::take().is_none(),
|
kaptan_err_reportable::take().is_none(),
|
||||||
"a cached command replay must not report the error again"
|
"a cached command replay must not report the error again"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
use kaptan_config::{
|
use kaptan_config::{
|
||||||
ConfigState, ConfigValue, FieldDescriptor, FieldId, ValidationRule, ValueKind,
|
ConfigState, ConfigValue, FieldDescriptor, FieldId, ValidationRule, ValueKind,
|
||||||
};
|
};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_mavlink::message::Message;
|
use kaptan_mavlink::message::Message;
|
||||||
use kaptan_mavlink::message::kaptan::{
|
use kaptan_mavlink::message::kaptan::{
|
||||||
KAPTAN_CONFIG_DESCRIPTOR_DATA, KAPTAN_CONFIG_ENUM_OPTION_DATA, KAPTAN_CONFIG_INFO_DATA,
|
KAPTAN_CONFIG_DESCRIPTOR_DATA, KAPTAN_CONFIG_ENUM_OPTION_DATA, KAPTAN_CONFIG_INFO_DATA,
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-config-derive = { path = "../kaptan-config-derive" }
|
kaptan-config-derive = { path = "../kaptan-config-derive" }
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-log = { path = "../kaptan-log" }
|
kaptan-log = { path = "../kaptan-log" }
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//! Transport-neutral typed configuration fields and descriptors.
|
//! Transport-neutral typed configuration fields and descriptors.
|
||||||
|
|
||||||
use crate::{ConfigViolation, ValidationRule};
|
use crate::{ConfigViolation, ValidationRule};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
/// Maximum choices representable by one enum-backed field.
|
/// Maximum choices representable by one enum-backed field.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::{
|
|||||||
ConfigModel, ConfigStore, ConfigValue, ConfigViolation, FieldDescriptor, FieldId,
|
ConfigModel, ConfigStore, ConfigValue, ConfigViolation, FieldDescriptor, FieldId,
|
||||||
FieldWriteError,
|
FieldWriteError,
|
||||||
};
|
};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
/// Observable state of the bounded configuration transaction slot.
|
/// Observable state of the bounded configuration transaction slot.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
//! field IDs and therefore also accepts a complete, uniquely identified set in
|
//! field IDs and therefore also accepts a complete, uniquely identified set in
|
||||||
//! another order.
|
//! another order.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
use crate::{ConfigModel, ConfigValue, FieldId, FieldWriteError, ValueKind};
|
use crate::{ConfigModel, ConfigValue, FieldId, FieldWriteError, ValueKind};
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ version.workspace = true
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-math = { path = "../kaptan-math" }
|
kaptan-math = { path = "../kaptan-math" }
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_math::{Frd, Ned, UnitQuaternion, Vector3, sqrt};
|
use kaptan_math::{Frd, Ned, UnitQuaternion, Vector3, sqrt};
|
||||||
|
|
||||||
/// Body-frame angular rate in radians per second.
|
/// Body-frame angular rate in radians per second.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ version.workspace = true
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-dma = { path = "../kaptan-dma" }
|
kaptan-dma = { path = "../kaptan-dma" }
|
||||||
kaptan-mavlink = { path = "../kaptan-mavlink" }
|
kaptan-mavlink = { path = "../kaptan-mavlink" }
|
||||||
kaptan-sensor = { path = "../kaptan-sensor" }
|
kaptan-sensor = { path = "../kaptan-sensor" }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use kaptan_dma::TxCompletion;
|
use kaptan_dma::TxCompletion;
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_mavlink::message::MessageData;
|
use kaptan_mavlink::message::MessageData;
|
||||||
use kaptan_mavlink::{
|
use kaptan_mavlink::{
|
||||||
MavlinkFrame,
|
MavlinkFrame,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ version.workspace = true
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-log = { path = "../kaptan-log" }
|
kaptan-log = { path = "../kaptan-log" }
|
||||||
kaptan-mavlink = { path = "../kaptan-mavlink", default-features = false, features = ["dialect-kaptan"] }
|
kaptan-mavlink = { path = "../kaptan-mavlink", default-features = false, features = ["dialect-kaptan"] }
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! MAVLink projection for Kaptan logs and typed firmware errors.
|
//! MAVLink projection for Kaptan logs and reportable firmware errors.
|
||||||
//!
|
//!
|
||||||
//! This adapter creates generated payload data only. A platform-owned link is
|
//! This adapter creates generated payload data only. A platform-owned link is
|
||||||
//! solely responsible for MAVLink framing, bounded admission, DMA, and retry
|
//! solely responsible for MAVLink framing, bounded admission, DMA, and retry
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate std;
|
extern crate std;
|
||||||
|
|
||||||
use kaptan_err_propagate::ErrorRecord;
|
use kaptan_err_reportable::ErrorRecord;
|
||||||
use kaptan_log::{Level, LogRecord, MAXIMUM_LOG_TEXT_BYTES};
|
use kaptan_log::{Level, LogRecord, MAXIMUM_LOG_TEXT_BYTES};
|
||||||
use kaptan_mavlink::message::kaptan::{KAPTAN_ERROR_DATA, KAPTAN_LOG_DATA, KaptanLogFlags};
|
use kaptan_mavlink::message::kaptan::{KAPTAN_ERROR_DATA, KAPTAN_LOG_DATA, KaptanLogFlags};
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ pub fn encode_log(record: &LogRecord) -> KAPTAN_LOG_DATA {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes one typed firmware error as its sole wire message.
|
/// Encodes one reportable firmware error as its sole wire message.
|
||||||
pub fn encode_error(record: &ErrorRecord) -> KAPTAN_ERROR_DATA {
|
pub fn encode_error(record: &ErrorRecord) -> KAPTAN_ERROR_DATA {
|
||||||
let source = record.raised_at().as_bytes();
|
let source = record.raised_at().as_bytes();
|
||||||
let mut length = source.len().min(ERROR_RAISED_AT_BYTES);
|
let mut length = source.len().min(ERROR_RAISED_AT_BYTES);
|
||||||
@@ -63,7 +63,7 @@ const fn mavlink_severity(level: Level) -> u8 {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{LOG_MESSAGE_BYTES, encode_error, encode_log};
|
use super::{LOG_MESSAGE_BYTES, encode_error, encode_log};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_log::{Level, LogFlags, LogRecord, LogText};
|
use kaptan_log::{Level, LogFlags, LogRecord, LogText};
|
||||||
use kaptan_mavlink::{
|
use kaptan_mavlink::{
|
||||||
MavlinkVersion,
|
MavlinkVersion,
|
||||||
@@ -80,8 +80,8 @@ mod tests {
|
|||||||
Transfer,
|
Transfer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn report_typed_error() -> Result<(), TestError> {
|
fn report_reportable_error() -> Result<(), TestError> {
|
||||||
Err(TestError::Transfer)
|
Err(TestError::Transfer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,9 +148,9 @@ mod tests {
|
|||||||
Ok(MavMessage::KAPTAN_LOG(decoded)) if decoded == data
|
Ok(MavMessage::KAPTAN_LOG(decoded)) if decoded == data
|
||||||
));
|
));
|
||||||
|
|
||||||
while kaptan_err_propagate::take().is_some() {}
|
while kaptan_err_reportable::take().is_some() {}
|
||||||
assert_eq!(report_typed_error(), Err(TestError::Transfer));
|
assert_eq!(report_reportable_error(), Err(TestError::Transfer));
|
||||||
let error = kaptan_err_propagate::take().expect("typed error retained");
|
let error = kaptan_err_reportable::take().expect("reportable error retained");
|
||||||
let error_data = encode_error(&error);
|
let error_data = encode_error(&error);
|
||||||
assert_eq!(error_data.error_id, error.id());
|
assert_eq!(error_data.error_id, error.id());
|
||||||
assert_eq!(KAPTAN_ERROR_DATA::ENCODED_LEN, 98);
|
assert_eq!(KAPTAN_ERROR_DATA::ENCODED_LEN, 98);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ version.workspace = true
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-sensor = { path = "../kaptan-sensor" }
|
kaptan-sensor = { path = "../kaptan-sensor" }
|
||||||
kaptan-i2c = { path = "../kaptan-i2c" }
|
kaptan-i2c = { path = "../kaptan-i2c" }
|
||||||
kaptan-spi = { path = "../kaptan-spi" }
|
kaptan-spi = { path = "../kaptan-spi" }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! ICM-42688-P operation errors.
|
//! ICM-42688-P operation errors.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
/// ICM-42688-P operation failure.
|
/// ICM-42688-P operation failure.
|
||||||
#[derive(Debug, Eq, PartialEq, KaptanError)]
|
#[derive(Debug, Eq, PartialEq, KaptanError)]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! LIDAR-Lite v3 operation errors.
|
//! LIDAR-Lite v3 operation errors.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
/// LIDAR-Lite v3 operation failure.
|
/// LIDAR-Lite v3 operation failure.
|
||||||
#[derive(Debug, Eq, PartialEq, KaptanError)]
|
#[derive(Debug, Eq, PartialEq, KaptanError)]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! MPU6000 operation errors.
|
//! MPU6000 operation errors.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
/// MPU6000 operation failure.
|
/// MPU6000 operation failure.
|
||||||
#[derive(Debug, Eq, PartialEq, KaptanError)]
|
#[derive(Debug, Eq, PartialEq, KaptanError)]
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
extern crate self as kaptan_err_propagate;
|
|
||||||
|
|
||||||
use kaptan_err_propagate_macros::KaptanError;
|
|
||||||
|
|
||||||
#[derive(Debug, KaptanError)]
|
|
||||||
enum MissingId {
|
|
||||||
Variant,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
use kaptan_err_propagate_macros::propagate;
|
|
||||||
|
|
||||||
#[propagate]
|
|
||||||
fn invalid() {}
|
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
use kaptan_err_propagate_macros::propagate;
|
|
||||||
|
|
||||||
extern crate self as kaptan_err_propagate;
|
|
||||||
|
|
||||||
pub trait ErrorReport {}
|
|
||||||
|
|
||||||
pub mod __private {
|
|
||||||
pub fn report_result<T, E: crate::ErrorReport>(_: &Result<T, E>, _: &'static str) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PlainError;
|
|
||||||
|
|
||||||
#[propagate]
|
|
||||||
fn invalid() -> Result<(), PlainError> {
|
|
||||||
Err(PlainError)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
error[E0277]: the trait bound `PlainError: ErrorReport` is not satisfied
|
|
||||||
--> tests/ui/no_error_report.rs:13:1
|
|
||||||
|
|
|
||||||
13 | #[propagate]
|
|
||||||
| ^^^^^^^^^^^^ the trait `ErrorReport` is not implemented for `PlainError`
|
|
||||||
|
|
|
||||||
help: this trait has no implementations, consider adding one
|
|
||||||
--> tests/ui/no_error_report.rs:5:1
|
|
||||||
|
|
|
||||||
5 | pub trait ErrorReport {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
note: required by a bound in `report_result`
|
|
||||||
--> tests/ui/no_error_report.rs:8:32
|
|
||||||
|
|
|
||||||
8 | pub fn report_result<T, E: crate::ErrorReport>(_: &Result<T, E>, _: &'static str) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^ required by this bound in `report_result`
|
|
||||||
= note: this error originates in the attribute macro `propagate` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kaptan-err-propagate-macros"
|
name = "kaptan-err-reportable-macros"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
+20
-20
@@ -1,4 +1,4 @@
|
|||||||
//! Attribute expansion for `kaptan-err-propagate`.
|
//! Attribute expansion for `kaptan-err-reportable`.
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
@@ -8,7 +8,7 @@ use syn::{
|
|||||||
parse_quote, spanned::Spanned,
|
parse_quote, spanned::Spanned,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Implements `kaptan_err_propagate::ErrorReport`, [`core::fmt::Display`], and
|
/// Implements `kaptan_err_reportable::ReportableError`, [`core::fmt::Display`], and
|
||||||
/// [`core::error::Error`] for an explicitly numbered error enum.
|
/// [`core::error::Error`] for an explicitly numbered error enum.
|
||||||
///
|
///
|
||||||
/// Every variant must declare a stable nonzero
|
/// Every variant must declare a stable nonzero
|
||||||
@@ -34,7 +34,7 @@ pub fn propagate(arguments: TokenStream, input: TokenStream) -> TokenStream {
|
|||||||
if !arguments.is_empty() {
|
if !arguments.is_empty() {
|
||||||
return Error::new(
|
return Error::new(
|
||||||
proc_macro2::Span::call_site(),
|
proc_macro2::Span::call_site(),
|
||||||
"kaptan_err_propagate::propagate does not accept arguments",
|
"kaptan_err_reportable::propagate does not accept arguments",
|
||||||
)
|
)
|
||||||
.into_compile_error()
|
.into_compile_error()
|
||||||
.into();
|
.into();
|
||||||
@@ -53,22 +53,22 @@ fn expand(mut function: ItemFn) -> syn::Result<proc_macro2::TokenStream> {
|
|||||||
function.block = if function.sig.asyncness.is_some() {
|
function.block = if function.sig.asyncness.is_some() {
|
||||||
Box::new(syn::parse_quote!({
|
Box::new(syn::parse_quote!({
|
||||||
const __KAPTAN_RAISED_AT: &str = concat!(file!(), ":", line!());
|
const __KAPTAN_RAISED_AT: &str = concat!(file!(), ":", line!());
|
||||||
let __kaptan_err_propagate_result = (async #body).await;
|
let __kaptan_err_reportable_result = (async #body).await;
|
||||||
::kaptan_err_propagate::__private::report_result(
|
::kaptan_err_reportable::__private::report_result(
|
||||||
&__kaptan_err_propagate_result,
|
&__kaptan_err_reportable_result,
|
||||||
__KAPTAN_RAISED_AT,
|
__KAPTAN_RAISED_AT,
|
||||||
);
|
);
|
||||||
__kaptan_err_propagate_result
|
__kaptan_err_reportable_result
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Box::new(syn::parse_quote!({
|
Box::new(syn::parse_quote!({
|
||||||
const __KAPTAN_RAISED_AT: &str = concat!(file!(), ":", line!());
|
const __KAPTAN_RAISED_AT: &str = concat!(file!(), ":", line!());
|
||||||
let __kaptan_err_propagate_result = (|| #body)();
|
let __kaptan_err_reportable_result = (|| #body)();
|
||||||
::kaptan_err_propagate::__private::report_result(
|
::kaptan_err_reportable::__private::report_result(
|
||||||
&__kaptan_err_propagate_result,
|
&__kaptan_err_reportable_result,
|
||||||
__KAPTAN_RAISED_AT,
|
__KAPTAN_RAISED_AT,
|
||||||
);
|
);
|
||||||
__kaptan_err_propagate_result
|
__kaptan_err_reportable_result
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -80,32 +80,32 @@ fn validate_signature(function: &ItemFn) -> syn::Result<()> {
|
|||||||
if let Some(token) = signature.constness {
|
if let Some(token) = signature.constness {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
token.span(),
|
token.span(),
|
||||||
"kaptan_err_propagate::propagate does not support const functions",
|
"kaptan_err_reportable::propagate does not support const functions",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if let Some(token) = signature.unsafety {
|
if let Some(token) = signature.unsafety {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
token.span(),
|
token.span(),
|
||||||
"kaptan_err_propagate::propagate does not support unsafe functions",
|
"kaptan_err_reportable::propagate does not support unsafe functions",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if let Some(abi) = &signature.abi {
|
if let Some(abi) = &signature.abi {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
abi.span(),
|
abi.span(),
|
||||||
"kaptan_err_propagate::propagate does not support foreign-ABI functions",
|
"kaptan_err_reportable::propagate does not support foreign-ABI functions",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if let Some(variadic) = &signature.variadic {
|
if let Some(variadic) = &signature.variadic {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
variadic.span(),
|
variadic.span(),
|
||||||
"kaptan_err_propagate::propagate does not support variadic functions",
|
"kaptan_err_reportable::propagate does not support variadic functions",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(signature.output, ReturnType::Default) {
|
if matches!(signature.output, ReturnType::Default) {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
signature.output.span(),
|
signature.output.span(),
|
||||||
"kaptan_err_propagate::propagate requires an explicit Result<T, E> return type",
|
"kaptan_err_reportable::propagate requires an explicit Result<T, E> return type",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -168,7 +168,7 @@ fn expand_error(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
|
|||||||
Fields::Named(_) => quote!(Self::#variant_ident { .. }),
|
Fields::Named(_) => quote!(Self::#variant_ident { .. }),
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
#pattern => ::kaptan_err_propagate::ErrorId::new(#id)
|
#pattern => ::kaptan_err_reportable::ErrorId::new(#id)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
||||||
@@ -183,8 +183,8 @@ fn expand_error(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
|
|||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#(#identities)*
|
#(#identities)*
|
||||||
|
|
||||||
impl #impl_generics ::kaptan_err_propagate::ErrorReport for #ident #type_generics #where_clause {
|
impl #impl_generics ::kaptan_err_reportable::ReportableError for #ident #type_generics #where_clause {
|
||||||
fn error_id(&self) -> ::kaptan_err_propagate::ErrorId {
|
fn error_id(&self) -> ::kaptan_err_reportable::ErrorId {
|
||||||
match self {
|
match self {
|
||||||
#(#arms),*
|
#(#arms),*
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ fn expand_error(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
|
|||||||
formatter: &mut ::core::fmt::Formatter<'_>,
|
formatter: &mut ::core::fmt::Formatter<'_>,
|
||||||
) -> ::core::fmt::Result {
|
) -> ::core::fmt::Result {
|
||||||
::core::fmt::Display::fmt(
|
::core::fmt::Display::fmt(
|
||||||
&<Self as ::kaptan_err_propagate::ErrorReport>::error_id(self).get(),
|
&<Self as ::kaptan_err_reportable::ReportableError>::error_id(self).get(),
|
||||||
formatter,
|
formatter,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
File renamed without changes.
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
use kaptan_err_propagate_macros::propagate;
|
use kaptan_err_reportable_macros::propagate;
|
||||||
|
|
||||||
#[propagate(report)]
|
#[propagate(report)]
|
||||||
fn invalid() -> Result<(), ()> {
|
fn invalid() -> Result<(), ()> {
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
error: kaptan_err_propagate::propagate does not accept arguments
|
error: kaptan_err_reportable::propagate does not accept arguments
|
||||||
--> tests/ui/arguments.rs:3:1
|
--> tests/ui/arguments.rs:3:1
|
||||||
|
|
|
|
||||||
3 | #[propagate(report)]
|
3 | #[propagate(report)]
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
use kaptan_err_propagate_macros::propagate;
|
use kaptan_err_reportable_macros::propagate;
|
||||||
|
|
||||||
#[propagate]
|
#[propagate]
|
||||||
const fn invalid() -> Result<(), ()> {
|
const fn invalid() -> Result<(), ()> {
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
error: kaptan_err_propagate::propagate does not support const functions
|
error: kaptan_err_reportable::propagate does not support const functions
|
||||||
--> tests/ui/const_fn.rs:4:1
|
--> tests/ui/const_fn.rs:4:1
|
||||||
|
|
|
|
||||||
4 | const fn invalid() -> Result<(), ()> {
|
4 | const fn invalid() -> Result<(), ()> {
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
extern crate self as kaptan_err_propagate;
|
extern crate self as kaptan_err_reportable;
|
||||||
|
|
||||||
use kaptan_err_propagate_macros::KaptanError;
|
use kaptan_err_reportable_macros::KaptanError;
|
||||||
|
|
||||||
#[derive(Debug, KaptanError)]
|
#[derive(Debug, KaptanError)]
|
||||||
enum DuplicateId {
|
enum DuplicateId {
|
||||||
File renamed without changes.
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
extern crate self as kaptan_err_propagate;
|
extern crate self as kaptan_err_reportable;
|
||||||
|
|
||||||
use kaptan_err_propagate_macros::KaptanError;
|
use kaptan_err_reportable_macros::KaptanError;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct ErrorId(u16);
|
pub struct ErrorId(u16);
|
||||||
@@ -15,7 +15,7 @@ impl ErrorId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ErrorReport {
|
pub trait ReportableError {
|
||||||
fn error_id(&self) -> ErrorId;
|
fn error_id(&self) -> ErrorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
File renamed without changes.
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
extern crate self as kaptan_err_propagate;
|
extern crate self as kaptan_err_reportable;
|
||||||
|
|
||||||
use kaptan_err_propagate_macros::KaptanError;
|
use kaptan_err_reportable_macros::KaptanError;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct ErrorId(u16);
|
pub struct ErrorId(u16);
|
||||||
@@ -15,7 +15,7 @@ impl ErrorId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ErrorReport {
|
pub trait ReportableError {
|
||||||
fn error_id(&self) -> ErrorId;
|
fn error_id(&self) -> ErrorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
extern crate self as kaptan_err_reportable;
|
||||||
|
|
||||||
|
use kaptan_err_reportable_macros::KaptanError;
|
||||||
|
|
||||||
|
#[derive(Debug, KaptanError)]
|
||||||
|
enum MissingId {
|
||||||
|
Variant,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
File renamed without changes.
@@ -0,0 +1,6 @@
|
|||||||
|
use kaptan_err_reportable_macros::propagate;
|
||||||
|
|
||||||
|
#[propagate]
|
||||||
|
fn invalid() {}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
error: kaptan_err_propagate::propagate requires an explicit Result<T, E> return type
|
error: kaptan_err_reportable::propagate requires an explicit Result<T, E> return type
|
||||||
--> tests/ui/missing_return.rs:3:1
|
--> tests/ui/missing_return.rs:3:1
|
||||||
|
|
|
|
||||||
3 | #[propagate]
|
3 | #[propagate]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
use kaptan_err_reportable_macros::propagate;
|
||||||
|
|
||||||
|
extern crate self as kaptan_err_reportable;
|
||||||
|
|
||||||
|
pub trait ReportableError {}
|
||||||
|
|
||||||
|
pub mod __private {
|
||||||
|
pub fn report_result<T, E: crate::ReportableError>(_: &Result<T, E>, _: &'static str) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PlainError;
|
||||||
|
|
||||||
|
#[propagate]
|
||||||
|
fn invalid() -> Result<(), PlainError> {
|
||||||
|
Err(PlainError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
error[E0277]: the trait bound `PlainError: ReportableError` is not satisfied
|
||||||
|
--> tests/ui/no_error_report.rs:13:1
|
||||||
|
|
|
||||||
|
13 | #[propagate]
|
||||||
|
| ^^^^^^^^^^^^ the trait `ReportableError` is not implemented for `PlainError`
|
||||||
|
|
|
||||||
|
help: this trait has no implementations, consider adding one
|
||||||
|
--> tests/ui/no_error_report.rs:5:1
|
||||||
|
|
|
||||||
|
5 | pub trait ReportableError {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: required by a bound in `report_result`
|
||||||
|
--> tests/ui/no_error_report.rs:8:32
|
||||||
|
|
|
||||||
|
8 | pub fn report_result<T, E: crate::ReportableError>(_: &Result<T, E>, _: &'static str) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `report_result`
|
||||||
|
= note: this error originates in the attribute macro `propagate` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
use kaptan_err_propagate_macros::propagate;
|
use kaptan_err_reportable_macros::propagate;
|
||||||
|
|
||||||
extern crate self as kaptan_err_propagate;
|
extern crate self as kaptan_err_reportable;
|
||||||
|
|
||||||
pub mod __private {
|
pub mod __private {
|
||||||
pub fn report_result<T, E>(_: &Result<T, E>, _: &'static str) {}
|
pub fn report_result<T, E>(_: &Result<T, E>, _: &'static str) {}
|
||||||
File renamed without changes.
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
use kaptan_err_propagate_macros::KaptanError;
|
use kaptan_err_reportable_macros::KaptanError;
|
||||||
|
|
||||||
#[derive(KaptanError)]
|
#[derive(KaptanError)]
|
||||||
struct NotAnError {
|
struct NotAnError {
|
||||||
File renamed without changes.
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
use kaptan_err_propagate_macros::KaptanError;
|
use kaptan_err_reportable_macros::KaptanError;
|
||||||
|
|
||||||
#[derive(KaptanError)]
|
#[derive(KaptanError)]
|
||||||
union NotAnError {
|
union NotAnError {
|
||||||
File renamed without changes.
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
use kaptan_err_propagate_macros::propagate;
|
use kaptan_err_reportable_macros::propagate;
|
||||||
|
|
||||||
#[propagate]
|
#[propagate]
|
||||||
unsafe fn invalid() -> Result<(), ()> {
|
unsafe fn invalid() -> Result<(), ()> {
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
error: kaptan_err_propagate::propagate does not support unsafe functions
|
error: kaptan_err_reportable::propagate does not support unsafe functions
|
||||||
--> tests/ui/unsafe_fn.rs:4:1
|
--> tests/ui/unsafe_fn.rs:4:1
|
||||||
|
|
|
|
||||||
4 | unsafe fn invalid() -> Result<(), ()> {
|
4 | unsafe fn invalid() -> Result<(), ()> {
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
extern crate self as kaptan_err_propagate;
|
extern crate self as kaptan_err_reportable;
|
||||||
|
|
||||||
use kaptan_err_propagate_macros::KaptanError;
|
use kaptan_err_reportable_macros::KaptanError;
|
||||||
|
|
||||||
#[derive(Debug, KaptanError)]
|
#[derive(Debug, KaptanError)]
|
||||||
enum ZeroId {
|
enum ZeroId {
|
||||||
File renamed without changes.
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kaptan-err-propagate"
|
name = "kaptan-err-reportable"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
@@ -9,4 +9,4 @@ version.workspace = true
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate-macros = { path = "../kaptan-err-propagate-macros" }
|
kaptan-err-reportable-macros = { path = "../kaptan-err-reportable-macros" }
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
//! Fixed, allocation-free typed-error ingress.
|
//! Fixed, allocation-free reportable-error ingress.
|
||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
@@ -68,7 +68,7 @@ pub(crate) fn publish(id: ErrorId, raised_at: &'static str) {
|
|||||||
GLOBAL_INGRESS.publish(id, raised_at);
|
GLOBAL_INGRESS.publish(id, raised_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes the pending typed firmware error, if one exists.
|
/// Takes the pending reportable firmware error, if one exists.
|
||||||
pub fn take() -> Option<ErrorRecord> {
|
pub fn take() -> Option<ErrorRecord> {
|
||||||
GLOBAL_INGRESS.take()
|
GLOBAL_INGRESS.take()
|
||||||
}
|
}
|
||||||
+10
-9
@@ -1,12 +1,13 @@
|
|||||||
//! Bounded typed firmware errors and function-boundary propagation.
|
//! Stable reportable firmware errors with bounded diagnostic ingress.
|
||||||
//!
|
//!
|
||||||
//! This crate owns error identity and ingress. It contains no logging levels,
|
//! This crate owns error identity and ingress. It contains no logging levels,
|
||||||
//! filtering, MAVLink, board, filesystem, or clock dependency.
|
//! filtering, MAVLink, board, filesystem, or clock dependency.
|
||||||
//!
|
//!
|
||||||
//! `#[propagate]` reports at each annotated boundary. Annotate the terminal
|
//! `#[propagate]` turns an annotated function into a reporting point. When a
|
||||||
//! boundary where an error enters diagnostics; nested annotated callers would
|
//! reportable error leaves that function, the macro makes one reporting
|
||||||
//! attempt to report the same propagation again. The bounded ingress retaining
|
//! attempt. Nested annotated callers would therefore attempt to report the
|
||||||
//! only one pending error is backpressure, not semantic duplicate suppression.
|
//! same error again. The bounded ingress retaining only one pending error is
|
||||||
|
//! backpressure, not semantic duplicate suppression.
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
@@ -18,19 +19,19 @@ mod record;
|
|||||||
mod sink;
|
mod sink;
|
||||||
|
|
||||||
pub use ingress::take;
|
pub use ingress::take;
|
||||||
pub use kaptan_err_propagate_macros::{KaptanError, propagate};
|
pub use kaptan_err_reportable_macros::{KaptanError, propagate};
|
||||||
pub use record::{ErrorId, ErrorRecord, ErrorReport};
|
pub use record::{ErrorId, ErrorRecord, ReportableError};
|
||||||
pub use sink::ErrorSink;
|
pub use sink::ErrorSink;
|
||||||
|
|
||||||
/// Implementation details used only by macro expansions.
|
/// Implementation details used only by macro expansions.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod __private {
|
pub mod __private {
|
||||||
use crate::ErrorReport;
|
use crate::ReportableError;
|
||||||
|
|
||||||
/// Reports an error only when it is the final result leaving an annotated
|
/// Reports an error only when it is the final result leaving an annotated
|
||||||
/// function. Borrowing preserves the exact result returned to the caller.
|
/// function. Borrowing preserves the exact result returned to the caller.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn report_result<T, E: ErrorReport>(
|
pub fn report_result<T, E: ReportableError>(
|
||||||
result: &core::result::Result<T, E>,
|
result: &core::result::Result<T, E>,
|
||||||
raised_at: &'static str,
|
raised_at: &'static str,
|
||||||
) {
|
) {
|
||||||
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
//! Stable error IDs and bounded pending records.
|
//! Stable error IDs and bounded pending records.
|
||||||
|
|
||||||
/// Stable nonzero identity for one typed firmware error variant.
|
/// Stable nonzero identity for one reportable firmware error variant.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct ErrorId(u16);
|
pub struct ErrorId(u16);
|
||||||
@@ -21,18 +21,18 @@ impl ErrorId {
|
|||||||
/// Implemented by [`crate::KaptanError`] derives.
|
/// Implemented by [`crate::KaptanError`] derives.
|
||||||
///
|
///
|
||||||
/// Obtaining an ID never publishes, allocates, or changes safety state.
|
/// Obtaining an ID never publishes, allocates, or changes safety state.
|
||||||
pub trait ErrorReport {
|
pub trait ReportableError {
|
||||||
/// Returns the stable ID assigned to this error variant.
|
/// Returns the stable ID assigned to this error variant.
|
||||||
fn error_id(&self) -> ErrorId;
|
fn error_id(&self) -> ErrorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorReport for ErrorId {
|
impl ReportableError for ErrorId {
|
||||||
fn error_id(&self) -> ErrorId {
|
fn error_id(&self) -> ErrorId {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One reported typed firmware error and its reporting boundary.
|
/// One reported firmware error and its reporting point.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub struct ErrorRecord {
|
pub struct ErrorRecord {
|
||||||
id: ErrorId,
|
id: ErrorId,
|
||||||
@@ -49,7 +49,7 @@ impl ErrorRecord {
|
|||||||
self.id.get()
|
self.id.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile-time `file:line` of the propagation boundary that reported it.
|
/// Compile-time `file:line` of the reporting point.
|
||||||
pub const fn raised_at(self) -> &'static str {
|
pub const fn raised_at(self) -> &'static str {
|
||||||
self.raised_at
|
self.raised_at
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ mod tests {
|
|||||||
use super::{ErrorId, ErrorRecord};
|
use super::{ErrorId, ErrorRecord};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn record_keeps_only_the_explicit_id_and_reporting_boundary() {
|
fn record_keeps_only_the_explicit_id_and_reporting_point() {
|
||||||
let record = ErrorRecord::new(ErrorId::new(65004), "module.rs:42");
|
let record = ErrorRecord::new(ErrorId::new(65004), "module.rs:42");
|
||||||
assert_eq!(record.id(), 65004);
|
assert_eq!(record.id(), 65004);
|
||||||
assert_eq!(record.raised_at(), "module.rs:42");
|
assert_eq!(record.raised_at(), "module.rs:42");
|
||||||
+3
-3
@@ -1,10 +1,10 @@
|
|||||||
//! One-slot retry ownership for a typed-error sink.
|
//! One-slot retry ownership for a reportable-error sink.
|
||||||
|
|
||||||
use crate::ErrorRecord;
|
use crate::ErrorRecord;
|
||||||
|
|
||||||
/// Retains one typed error until a lower sink accepts it.
|
/// Retains one reportable error until a lower sink accepts it.
|
||||||
///
|
///
|
||||||
/// Typed errors are never filtered. A composition may give them priority over
|
/// Reportable errors are never filtered. A composition may give them priority over
|
||||||
/// best-effort logs without coupling the producer to its transport.
|
/// best-effort logs without coupling the producer to its transport.
|
||||||
pub struct ErrorSink {
|
pub struct ErrorSink {
|
||||||
pending: Option<ErrorRecord>,
|
pending: Option<ErrorRecord>,
|
||||||
+26
-26
@@ -1,4 +1,4 @@
|
|||||||
use kaptan_err_propagate::{ErrorId, ErrorReport, KaptanError};
|
use kaptan_err_reportable::{ErrorId, KaptanError, ReportableError};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, KaptanError)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, KaptanError)]
|
||||||
enum TestError {
|
enum TestError {
|
||||||
@@ -26,18 +26,18 @@ fn middle() -> Result<(), TestError> {
|
|||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn succeeds() -> Result<u8, TestError> {
|
fn succeeds() -> Result<u8, TestError> {
|
||||||
Ok(7)
|
Ok(7)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn annotated_outer() -> Result<(), TestError> {
|
fn annotated_outer() -> Result<(), TestError> {
|
||||||
middle()?;
|
middle()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn annotated_inner() -> Result<(), TestError> {
|
fn annotated_inner() -> Result<(), TestError> {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
@@ -46,15 +46,15 @@ fn unannotated_outer() -> Result<(), TestError> {
|
|||||||
annotated_inner()
|
annotated_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn handles_inner_error() -> Result<(), TestError> {
|
fn handles_inner_error() -> Result<(), TestError> {
|
||||||
let _handled = fail().is_err();
|
let _handled = fail().is_err();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn returns_explicit_error(fail_at_boundary: bool) -> Result<(), TestError> {
|
fn returns_explicit_error(report_error: bool) -> Result<(), TestError> {
|
||||||
if fail_at_boundary {
|
if report_error {
|
||||||
return Err(TestError::Failed);
|
return Err(TestError::Failed);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -62,24 +62,24 @@ fn returns_explicit_error(fail_at_boundary: bool) -> Result<(), TestError> {
|
|||||||
|
|
||||||
type AliasedResult<T> = core::result::Result<T, TestError>;
|
type AliasedResult<T> = core::result::Result<T, TestError>;
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn returns_alias() -> AliasedResult<()> {
|
fn returns_alias() -> AliasedResult<()> {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn reports_final_converted_error() -> Result<(), OuterError> {
|
fn reports_converted_error() -> Result<(), OuterError> {
|
||||||
fail()?;
|
fail()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn reports_error_id() -> Result<(), ErrorId> {
|
fn reports_error_id() -> Result<(), ErrorId> {
|
||||||
Err(ErrorId::new(65003))
|
Err(ErrorId::new(65003))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
async fn async_boundary() -> Result<(), TestError> {
|
async fn async_reporting_point() -> Result<(), TestError> {
|
||||||
fail()?;
|
fail()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -87,28 +87,28 @@ async fn async_boundary() -> Result<(), TestError> {
|
|||||||
struct Service;
|
struct Service;
|
||||||
|
|
||||||
impl Service {
|
impl Service {
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn method(&self, fail_at_boundary: bool) -> Result<(), TestError> {
|
fn method(&self, report_error: bool) -> Result<(), TestError> {
|
||||||
if fail_at_boundary {
|
if report_error {
|
||||||
fail()?;
|
fail()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn take_record() -> kaptan_err_propagate::ErrorRecord {
|
fn take_record() -> kaptan_err_reportable::ErrorRecord {
|
||||||
kaptan_err_propagate::take().expect("escaping error must be reported")
|
kaptan_err_reportable::take().expect("escaping error must be reported")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reports_only_final_errors_leaving_annotated_boundaries() {
|
fn reports_only_errors_leaving_annotated_reporting_points() {
|
||||||
while kaptan_err_propagate::take().is_some() {}
|
while kaptan_err_reportable::take().is_some() {}
|
||||||
|
|
||||||
assert_eq!(succeeds(), Ok(7));
|
assert_eq!(succeeds(), Ok(7));
|
||||||
assert!(kaptan_err_propagate::take().is_none());
|
assert!(kaptan_err_reportable::take().is_none());
|
||||||
|
|
||||||
assert_eq!(handles_inner_error(), Ok(()));
|
assert_eq!(handles_inner_error(), Ok(()));
|
||||||
assert!(kaptan_err_propagate::take().is_none());
|
assert!(kaptan_err_reportable::take().is_none());
|
||||||
|
|
||||||
assert_eq!(annotated_outer(), Err(TestError::Failed));
|
assert_eq!(annotated_outer(), Err(TestError::Failed));
|
||||||
assert_eq!(take_record().id(), TestError::Failed.error_id().get());
|
assert_eq!(take_record().id(), TestError::Failed.error_id().get());
|
||||||
@@ -123,7 +123,7 @@ fn reports_only_final_errors_leaving_annotated_boundaries() {
|
|||||||
assert_eq!(take_record().id(), TestError::Failed.error_id().get());
|
assert_eq!(take_record().id(), TestError::Failed.error_id().get());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
reports_final_converted_error(),
|
reports_converted_error(),
|
||||||
Err(OuterError::Converted(TestError::Failed))
|
Err(OuterError::Converted(TestError::Failed))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -135,9 +135,9 @@ fn reports_only_final_errors_leaving_annotated_boundaries() {
|
|||||||
assert_eq!(take_record().id(), 65003);
|
assert_eq!(take_record().id(), 65003);
|
||||||
|
|
||||||
assert_eq!(Service.method(false), Ok(()));
|
assert_eq!(Service.method(false), Ok(()));
|
||||||
assert!(kaptan_err_propagate::take().is_none());
|
assert!(kaptan_err_reportable::take().is_none());
|
||||||
|
|
||||||
let mut future = core::pin::pin!(async_boundary());
|
let mut future = core::pin::pin!(async_reporting_point());
|
||||||
let mut context = core::task::Context::from_waker(core::task::Waker::noop());
|
let mut context = core::task::Context::from_waker(core::task::Waker::noop());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
core::future::Future::poll(future.as_mut(), &mut context),
|
core::future::Future::poll(future.as_mut(), &mut context),
|
||||||
@@ -10,6 +10,6 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-config = { path = "../kaptan-config" }
|
kaptan-config = { path = "../kaptan-config" }
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-log = { path = "../kaptan-log" }
|
kaptan-log = { path = "../kaptan-log" }
|
||||||
minicbor = { version = "0.25", features = ["derive"] }
|
minicbor = { version = "0.25", features = ["derive"] }
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
use kaptan_config::{
|
use kaptan_config::{
|
||||||
ConfigModel, ConfigValue, ConfigViolation, FieldWriteError, ValidationRule, ValueKind,
|
ConfigModel, ConfigValue, ConfigViolation, FieldWriteError, ValidationRule, ValueKind,
|
||||||
};
|
};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use minicbor::{Decoder, Encoder, encode::Write};
|
use minicbor::{Decoder, Encoder, encode::Write};
|
||||||
|
|
||||||
use crate::{CandidateProfile, FORMAT_VERSION, SCHEMA_ID, VehicleCapabilities};
|
use crate::{CandidateProfile, FORMAT_VERSION, SCHEMA_ID, VehicleCapabilities};
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ version.workspace = true
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
/// Failure reported by a checked mathematical operation.
|
/// Failure reported by a checked mathematical operation.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ sensor-telemetry = ["dep:kaptan-sensor"]
|
|||||||
dialect-kaptan = []
|
dialect-kaptan = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-dma = { path = "../kaptan-dma" }
|
kaptan-dma = { path = "../kaptan-dma" }
|
||||||
kaptan-sensor = { path = "../kaptan-sensor", optional = true }
|
kaptan-sensor = { path = "../kaptan-sensor", optional = true }
|
||||||
kaptan-tx = { path = "../kaptan-tx" }
|
kaptan-tx = { path = "../kaptan-tx" }
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
<!-- Kaptan-reserved development block. Register these IDs before release. -->
|
<!-- Kaptan-reserved development block. Register these IDs before release. -->
|
||||||
<messages>
|
<messages>
|
||||||
<message id="51021" name="KAPTAN_ERROR">
|
<message id="51021" name="KAPTAN_ERROR">
|
||||||
<description>Typed firmware error reported when an Err leaves an annotated propagation boundary. This is distinct from every logging macro, which emits KAPTAN_LOG. The stable ID is explicitly assigned to the Rust error variant. Structured configuration failures remain authoritative in KAPTAN_CONFIG_RESULT.</description>
|
<description>Reportable firmware error emitted when an Err leaves an annotated reporting point. This is distinct from every logging macro, which emits KAPTAN_LOG. The stable ID is explicitly assigned to the Rust error variant. Structured configuration failures remain authoritative in KAPTAN_CONFIG_RESULT.</description>
|
||||||
<field type="uint16_t" name="error_id">Stable explicitly assigned error catalog ID. Zero is reserved.</field>
|
<field type="uint16_t" name="error_id">Stable explicitly assigned error catalog ID. Zero is reserved.</field>
|
||||||
<field type="uint8_t[96]" name="raised_at">Zero-padded compile-time file:line of the propagation boundary that reported the error.</field>
|
<field type="uint8_t[96]" name="raised_at">Zero-padded compile-time file:line of the reporting point.</field>
|
||||||
</message>
|
</message>
|
||||||
</messages>
|
</messages>
|
||||||
</mavlink>
|
</mavlink>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//! MAVLink frame encoding and UART transmission API.
|
//! MAVLink frame encoding and UART transmission API.
|
||||||
|
|
||||||
use kaptan_dma::{DmaTxBufferFactory, DmaTxEngine, TxCompletion};
|
use kaptan_dma::{DmaTxBufferFactory, DmaTxEngine, TxCompletion};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_tx::{PendingFrame, TransmitQueue};
|
use kaptan_tx::{PendingFrame, TransmitQueue};
|
||||||
|
|
||||||
use crate::MavlinkFrame;
|
use crate::MavlinkFrame;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ default = []
|
|||||||
# executable. It is not part of a board build.
|
# executable. It is not part of a board build.
|
||||||
sitl = ["dep:kaptan-sensor"]
|
sitl = ["dep:kaptan-sensor"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-math = { path = "../kaptan-math" }
|
kaptan-math = { path = "../kaptan-math" }
|
||||||
kaptan-sensor = { path = "../kaptan-sensor", optional = true }
|
kaptan-sensor = { path = "../kaptan-sensor", optional = true }
|
||||||
kaptan-time = { path = "../kaptan-time" }
|
kaptan-time = { path = "../kaptan-time" }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Fixed-size multiplicative error-state Kalman filter.
|
//! Fixed-size multiplicative error-state Kalman filter.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_math::{Frd, MathError, Ned, Sensor, UnitQuaternion, Vector3, sqrt};
|
use kaptan_math::{Frd, MathError, Ned, Sensor, UnitQuaternion, Vector3, sqrt};
|
||||||
use kaptan_time::Timestamp;
|
use kaptan_time::Timestamp;
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ version.workspace = true
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../kaptan-err-reportable" }
|
||||||
kaptan-time = { path = "../kaptan-time" }
|
kaptan-time = { path = "../kaptan-time" }
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_time::Timestamp;
|
use kaptan_time::Timestamp;
|
||||||
|
|
||||||
/// Supervisor arming state.
|
/// Supervisor arming state.
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ workspace = true
|
|||||||
test = false
|
test = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../../libs/kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../../libs/kaptan-err-reportable" }
|
||||||
kaptan-config = { path = "../../libs/kaptan-config" }
|
kaptan-config = { path = "../../libs/kaptan-config" }
|
||||||
kaptan-config-mavlink = { path = "../../libs/kaptan-config-mavlink" }
|
kaptan-config-mavlink = { path = "../../libs/kaptan-config-mavlink" }
|
||||||
kaptan-data-channel = { path = "../../libs/kaptan-data-channel" }
|
kaptan-data-channel = { path = "../../libs/kaptan-data-channel" }
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ use kaptan_drivers::{
|
|||||||
},
|
},
|
||||||
mtf01::Mtf01Service,
|
mtf01::Mtf01Service,
|
||||||
};
|
};
|
||||||
use kaptan_err_propagate::{ErrorId, ErrorSink};
|
use kaptan_err_reportable::{ErrorId, ErrorSink};
|
||||||
use kaptan_log::{DeliveryClass, LogSinkQueue, TransportAdmission};
|
use kaptan_log::{DeliveryClass, LogSinkQueue, TransportAdmission};
|
||||||
use kaptan_spi::SpiCompletion;
|
use kaptan_spi::SpiCompletion;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
@@ -525,7 +525,7 @@ impl F722LidarState {
|
|||||||
let _ = publish_lidar_event(event);
|
let _ = publish_lidar_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
pub fn on_timer(&mut self) -> Result<(), StartupError> {
|
pub fn on_timer(&mut self) -> Result<(), StartupError> {
|
||||||
if let Some(range) = self.range.as_mut() {
|
if let Some(range) = self.range.as_mut() {
|
||||||
if self.startup_ticks < LIDAR_STARTUP_TICKS {
|
if self.startup_ticks < LIDAR_STARTUP_TICKS {
|
||||||
@@ -568,7 +568,7 @@ pub fn process_imu(imu: &mut F722Imu, events: u8) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn accept_imu_event(event: ImuEvent) -> Result<(), ErrorId> {
|
fn accept_imu_event(event: ImuEvent) -> Result<(), ErrorId> {
|
||||||
match event {
|
match event {
|
||||||
ImuEvent::Sample(sample) => {
|
ImuEvent::Sample(sample) => {
|
||||||
@@ -683,7 +683,7 @@ where
|
|||||||
|
|
||||||
fn drain_one_mavlink_diagnostic(&mut self) {
|
fn drain_one_mavlink_diagnostic(&mut self) {
|
||||||
if self.mavlink_errors.is_empty()
|
if self.mavlink_errors.is_empty()
|
||||||
&& let Some(record) = kaptan_err_propagate::take()
|
&& let Some(record) = kaptan_err_reportable::take()
|
||||||
{
|
{
|
||||||
let _ = self.mavlink_errors.publish_record(record);
|
let _ = self.mavlink_errors.publish_record(record);
|
||||||
}
|
}
|
||||||
@@ -789,7 +789,7 @@ pub fn record_mavlink_completion(completion: kaptan_dma::TxCompletion) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kaptan_err_propagate::propagate]
|
#[kaptan_err_reportable::propagate]
|
||||||
fn publish_lidar_event(
|
fn publish_lidar_event(
|
||||||
event: LidarLiteV3ServiceEvent<I2c1Error>,
|
event: LidarLiteV3ServiceEvent<I2c1Error>,
|
||||||
) -> Result<(), LidarError<I2c1Error>> {
|
) -> Result<(), LidarError<I2c1Error>> {
|
||||||
@@ -810,14 +810,14 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn transient_i2c_busy_is_retry_not_a_typed_lidar_fault() {
|
fn transient_i2c_busy_is_retry_not_a_typed_lidar_fault() {
|
||||||
while kaptan_err_propagate::take().is_some() {}
|
while kaptan_err_reportable::take().is_some() {}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
publish_lidar_event(LidarLiteV3ServiceEvent::Fault(LidarError::Start(
|
publish_lidar_event(LidarLiteV3ServiceEvent::Fault(LidarError::Start(
|
||||||
I2c1Error::Busy,
|
I2c1Error::Busy,
|
||||||
))),
|
))),
|
||||||
Ok(())
|
Ok(())
|
||||||
);
|
);
|
||||||
assert!(kaptan_err_propagate::take().is_none());
|
assert!(kaptan_err_reportable::take().is_none());
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
publish_lidar_event(LidarLiteV3ServiceEvent::Fault(LidarError::Start(
|
publish_lidar_event(LidarLiteV3ServiceEvent::Fault(LidarError::Start(
|
||||||
@@ -825,7 +825,7 @@ mod tests {
|
|||||||
))),
|
))),
|
||||||
Err(LidarError::Start(I2c1Error::InvalidLength))
|
Err(LidarError::Start(I2c1Error::InvalidLength))
|
||||||
));
|
));
|
||||||
assert!(kaptan_err_propagate::take().is_some());
|
assert!(kaptan_err_reportable::take().is_some());
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
publish_lidar_event(LidarLiteV3ServiceEvent::Fault(LidarError::Start(
|
publish_lidar_event(LidarLiteV3ServiceEvent::Fault(LidarError::Start(
|
||||||
@@ -833,6 +833,6 @@ mod tests {
|
|||||||
))),
|
))),
|
||||||
Err(LidarError::Start(I2c1Error::InvalidAddress))
|
Err(LidarError::Start(I2c1Error::InvalidAddress))
|
||||||
));
|
));
|
||||||
assert!(kaptan_err_propagate::take().is_some());
|
assert!(kaptan_err_reportable::take().is_some());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//! STM32F722 Pll216 clock-source assembly.
|
//! STM32F722 Pll216 clock-source assembly.
|
||||||
|
|
||||||
use super::peripherals::{DwtMicrosecondClock, select_pll216_profile};
|
use super::peripherals::{DwtMicrosecondClock, select_pll216_profile};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|
||||||
/// Core frequency in whole megahertz after selecting the PLL216 board profile.
|
/// Core frequency in whole megahertz after selecting the PLL216 board profile.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Deterministic STM32F722 PLL clock-source selection.
|
//! Deterministic STM32F722 PLL clock-source selection.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|
||||||
const CLOCK_SWITCH_POLL_LIMIT: u16 = 1_024;
|
const CLOCK_SWITCH_POLL_LIMIT: u16 = 1_024;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! STM32F722 I²C1 interrupt-driven controller.
|
//! STM32F722 I²C1 interrupt-driven controller.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_i2c::{I2cBus, I2cCompletion};
|
use kaptan_i2c::{I2cBus, I2cCompletion};
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
//! is generated after the last serial frame; transmit completion can occur
|
//! is generated after the last serial frame; transmit completion can occur
|
||||||
//! while the final serial clock is still in progress.
|
//! while the final serial clock is still in progress.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_spi::SpiCompletion;
|
use kaptan_spi::SpiCompletion;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
//! is generated after the last serial frame; transmit completion can occur
|
//! is generated after the last serial frame; transmit completion can occur
|
||||||
//! while the final serial clock is still in progress.
|
//! while the final serial clock is still in progress.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_spi::SpiCompletion;
|
use kaptan_spi::SpiCompletion;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//! DWT-backed monotonic microsecond clock for STM32F722.
|
//! DWT-backed monotonic microsecond clock for STM32F722.
|
||||||
|
|
||||||
use cortex_m::peripheral::{DCB, DWT};
|
use cortex_m::peripheral::{DCB, DWT};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_time::{MonotonicClock, Timestamp};
|
use kaptan_time::{MonotonicClock, Timestamp};
|
||||||
|
|
||||||
/// A DWT cycle counter extended into monotonic microseconds.
|
/// A DWT cycle counter extended into monotonic microseconds.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! STM32F722 USART routes used by supported boards.
|
//! STM32F722 USART routes used by supported boards.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|
||||||
/// UART baud-rate configuration error.
|
/// UART baud-rate configuration error.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
//! cannot be selected at construction.
|
//! cannot be selected at construction.
|
||||||
|
|
||||||
use kaptan_dma::{DmaReadableBuffer, DmaTxEngine, TxCompletion};
|
use kaptan_dma::{DmaReadableBuffer, DmaTxEngine, TxCompletion};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|
||||||
use super::Usart1Tx;
|
use super::Usart1Tx;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
//! cannot be selected at construction.
|
//! cannot be selected at construction.
|
||||||
|
|
||||||
use kaptan_dma::{DmaReadableBuffer, DmaTxEngine, TxCompletion};
|
use kaptan_dma::{DmaReadableBuffer, DmaTxEngine, TxCompletion};
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|
||||||
use super::Usart2Tx;
|
use super::Usart2Tx;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use kaptan_drivers::{
|
|||||||
icm42688::{Error as Icm42688Error, Icm42688, Icm42688Service, Icm42688ServiceEvent},
|
icm42688::{Error as Icm42688Error, Icm42688, Icm42688Service, Icm42688ServiceEvent},
|
||||||
mpu6000::{Error as Mpu6000Error, Mpu6000, Mpu6000Config, Mpu6000Service, Mpu6000ServiceEvent},
|
mpu6000::{Error as Mpu6000Error, Mpu6000, Mpu6000Config, Mpu6000Service, Mpu6000ServiceEvent},
|
||||||
};
|
};
|
||||||
use kaptan_err_propagate::{ErrorId, ErrorReport};
|
use kaptan_err_reportable::{ErrorId, ReportableError};
|
||||||
use kaptan_sensor::imu::ImuSnapshot;
|
use kaptan_sensor::imu::ImuSnapshot;
|
||||||
use kaptan_spi::SpiCompletion;
|
use kaptan_spi::SpiCompletion;
|
||||||
use stm32f7::stm32f722;
|
use stm32f7::stm32f722;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use kaptan_config::Config;
|
use kaptan_config::Config;
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
|
|
||||||
pub use kaptan_drivers::mpu6000::{
|
pub use kaptan_drivers::mpu6000::{
|
||||||
AccelerometerRange, DigitalLowPassFilter, GyroscopeRange, Mpu6000Config,
|
AccelerometerRange, DigitalLowPassFilter, GyroscopeRange, Mpu6000Config,
|
||||||
|
|||||||
@@ -369,10 +369,10 @@ fn mavlink_transport_faults_do_not_recurse_or_retain_dead_accounting() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn f722_producers_keep_logs_and_typed_errors_separate() {
|
fn f722_producers_keep_logs_and_reportable_errors_separate() {
|
||||||
let board = platform_source("src/f722/board.rs");
|
let board = platform_source("src/f722/board.rs");
|
||||||
let logger = platform_source("../../libs/kaptan-log/src/facade.rs");
|
let logger = platform_source("../../libs/kaptan-log/src/facade.rs");
|
||||||
let errors = platform_source("../../libs/kaptan-err-propagate/src/ingress.rs");
|
let errors = platform_source("../../libs/kaptan-err-reportable/src/ingress.rs");
|
||||||
|
|
||||||
for macro_name in [
|
for macro_name in [
|
||||||
"kaptan_log::debug!",
|
"kaptan_log::debug!",
|
||||||
@@ -385,7 +385,7 @@ fn f722_producers_keep_logs_and_typed_errors_separate() {
|
|||||||
"f722 does not exercise {macro_name}"
|
"f722 does not exercise {macro_name}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
assert!(board.contains("#[kaptan_err_propagate::propagate]"));
|
assert!(board.contains("#[kaptan_err_reportable::propagate]"));
|
||||||
assert!(!board.contains("report_error"));
|
assert!(!board.contains("report_error"));
|
||||||
assert!(!board.contains("report_static_error"));
|
assert!(!board.contains("report_static_error"));
|
||||||
assert!(logger.contains("GLOBAL_INGRESS_CAPACITY"));
|
assert!(logger.contains("GLOBAL_INGRESS_CAPACITY"));
|
||||||
|
|||||||
@@ -539,7 +539,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn packet_and_history_decode_a_typed_kaptan_error() {
|
fn packet_and_history_decode_a_reportable_kaptan_error() {
|
||||||
let raised_at_text = "platforms/stm32f7/src/f722/board.rs:572";
|
let raised_at_text = "platforms/stm32f7/src/f722/board.rs:572";
|
||||||
let mut raised_at = [0; 96];
|
let mut raised_at = [0; 96];
|
||||||
raised_at[..raised_at_text.len()].copy_from_slice(raised_at_text.as_bytes());
|
raised_at[..raised_at_text.len()].copy_from_slice(raised_at_text.as_bytes());
|
||||||
@@ -684,7 +684,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn malformed_typed_error_location_is_not_added_to_history() {
|
fn malformed_reportable_error_location_is_not_added_to_history() {
|
||||||
let mut raised_at = [0_u8; 96];
|
let mut raised_at = [0_u8; 96];
|
||||||
raised_at[0] = 0xff;
|
raised_at[0] = 0xff;
|
||||||
let mut frame = MavlinkFrame::new();
|
let mut frame = MavlinkFrame::new();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ version.workspace = true
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kaptan-err-propagate = { path = "../../libs/kaptan-err-propagate" }
|
kaptan-err-reportable = { path = "../../libs/kaptan-err-reportable" }
|
||||||
kaptan-control = { path = "../../libs/kaptan-control" }
|
kaptan-control = { path = "../../libs/kaptan-control" }
|
||||||
kaptan-config = { path = "../../libs/kaptan-config" }
|
kaptan-config = { path = "../../libs/kaptan-config" }
|
||||||
kaptan-config-mavlink = { path = "../../libs/kaptan-config-mavlink" }
|
kaptan-config-mavlink = { path = "../../libs/kaptan-config-mavlink" }
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use kaptan_config::ConfigStore;
|
use kaptan_config::ConfigStore;
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use kaptan_flight_config::{
|
use kaptan_flight_config::{
|
||||||
CandidateProfile, CborEncodeError, CborError, MAXIMUM_CANDIDATE_BYTES, VehicleProfile,
|
CandidateProfile, CborEncodeError, CborError, MAXIMUM_CANDIDATE_BYTES, VehicleProfile,
|
||||||
decode_candidate, encode_candidate,
|
decode_candidate, encode_candidate,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//! dialect. It is confined to one host network namespace and is versioned so
|
//! dialect. It is confined to one host network namespace and is versioned so
|
||||||
//! malformed simulator traffic never becomes estimator or motor authority.
|
//! malformed simulator traffic never becomes estimator or motor authority.
|
||||||
|
|
||||||
use kaptan_err_propagate::KaptanError;
|
use kaptan_err_reportable::KaptanError;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
pub const SENSOR_PORT: u16 = 14_660;
|
pub const SENSOR_PORT: u16 = 14_660;
|
||||||
|
|||||||
Reference in new issue
Block a user