Skip to content

Commit

Permalink
Fixes doc tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nichtsfrei committed Dec 16, 2024
1 parent dbe087e commit 686e18d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
38 changes: 29 additions & 9 deletions rust/src/nasl/utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ This section briefly describes how to handle errors that occur during builtin fu


```rust

type ArgumentError = String;
struct InternalError {};
type BuiltinError = &'static str;

pub enum FnErrorKind {
Argument(ArgumentError),
Internal(InternalError),
Expand All @@ -26,6 +31,8 @@ As stated above, the metadata (return value, retryable) on how to handle a speci
### Return behavior
The return behavior of a given error specifies how an error should be handled during execution. This is specified by the following type:
```rust
use scannerlib::nasl::NaslValue;

enum ReturnBehavior {
ExitScript,
ReturnValue(NaslValue),
Expand All @@ -34,32 +41,45 @@ enum ReturnBehavior {
When the interpreter encounters an error with `ReturnBehavior::ExitScript` behavior, it will unsurprisingly exit the script. If it encounters an error with `ReturnBehavior::ReturnValue(val)`, it will return `val` and continue execution.

In the corresponding `From` impls, the `Argument` and `Internal` variants of `FnError` are automatically constructed with `ReturnBehavior::ExitScript`, meaning that they abort execution of the script. The `Builtin` variant is constructed with `ReturnBehavior::ReturnValue(NaslValue::Null)` by default, but this value can easily be overwritten when the error is created, for example:
```rust
```rust,compile_fail
use scannerlib::nasl::prelude::*;
use scannerlib::nasl::builtin::http::HttpError;
let handle = "/vts".to_string();
HttpError::HandleIdNotFound(handle).with(ReturnValue(-1))
```

### Retry behavior
Certain errors can be flagged as being solvable by retrying the operation that caused them. This is represented by a `retryable` boolean on `FnError`, which is `false` by default for all variants except for a specific internal error in the storage. However, this default behavior can be overwritten at error creation if needed, for example
```rust
HttpError::ConnectionFailed(...).with(Retryable)
```rust,compile_fail
use scannerlib::nasl::prelude::*;
use scannerlib::nasl::builtin::http::HttpError;
HttpError::IO(std::io::ErrorKind::ConnectionReset).with(Retryable)
```
I also added a small test to make sure that the interpreter does actually retry retryable errors.

## How to add a new error type for a builtin module
1. Add a custom error type for the builtin module. These can be of arbitrary form but a typical error type might look like
```rust
use scannerlib::nasl::prelude::*;
use thiserror::Error;

#[derive(Debug, Error)]
enum FooError {
#[error("Bar occurred.")]
Bar,
#[error("Baz occurred. Here is some more data: {0}")]
Baz(SomeData),
Baz(String),
}
```
This helps with keeping the error messages all in one place to ensure a common form.

2. Add this builtin error as a variant of the `BuiltinError` type described above.
```rust
```rust,compile_fail
enum BuiltinError {
...
Foo(FooError),
Expand All @@ -68,12 +88,12 @@ enum BuiltinError {
```

3. For convenience, some `From` impls and `TryFrom` impls can make the error type easier to use by enabling use of the question mark operator. I added a tiny macro that implements these traits (because the implementations are usually trivial), so this comes down to one line too:
```
```compile_fail
builtin_error_variant!(Foo, FooError);
```

This is all that is needed to make this error usable in NASL functions:
```rust
```rust,compile_fail
fn check(a: usize) -> Result<(), FooError> {
if a == 0 {
Err(FooError::Bar)
Expand All @@ -92,7 +112,7 @@ fn foo(a: usize) -> Result<usize, FnError> {

As a side note, NASL functions can also return any concrete `impl Into<FnError>` directly, so for this case we can also write

```rust
```rust,compile_fail
#[nasl_function]
fn foo(a: usize) -> Result<usize, FooError> {
if a == 0 {
Expand All @@ -106,7 +126,7 @@ fn foo(a: usize) -> Result<usize, FooError> {

Note that the above `From` impls that are automatically written by the `builtin_error_variant!` macro can also be manually implemented if one wants to specify defaults for a specific error variant. For example

```rust
```rust,compile_fail
impl From<FooError> for FnError {
fn from(e: FooError) -> FnError {
match e {
Expand Down
2 changes: 1 addition & 1 deletion rust/src/openvas/pref_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ where

// prepare vt preferences
for pref in &vt.parameters {
if let Some((prefid, class, name, value)) =
if let Some((prefid, class, name, _value)) =
nvt.preferences.iter().find_map(|p| {
if let Some(i) = p.id {
if i as u16 == pref.id {
Expand Down

0 comments on commit 686e18d

Please sign in to comment.