Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(remap, external docs): Document compile-time errors #6325

Merged
merged 15 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/reference/remap.cue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package metadata

#Remap: {
#Characteristic: {
anchor: "#\(name)"
anchor: name
name: string
title: string
description: string
Expand All @@ -26,6 +26,10 @@ package metadata
output?: #Event
}

if raises != _|_ {
diff?: string
}

notes?: [string, ...string]
warnings?: [string, ...string]
}
Expand All @@ -34,6 +38,7 @@ package metadata

concepts: _
description: string
errors: _
examples: [#Example, ...#Example]
expressions: _
features: _
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/remap/concepts.cue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package metadata

remap: {
#Concept: {
anchor: "#\(name)"
anchor: name
name: string
title: string
description: string
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/remap/concepts/function.cue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ remap: concepts: function: {
fallibility: {
title: "Fallibility"
description: """
Of particular note for functions is fallibility. [Error-safety](\(urls.vrl_error_safety)) is a defining
Of particular note for functions is fallibility. [Fail-safety](\(urls.vrl_fail_safety)) is a defining
characteristic of VRL and function fallibility is core to achieving that feature.
"""
}
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/remap/concepts/program.cue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ remap: concepts: program: {
title: "Program"
description: """
A VRL program is the highest-level concept. It is the end result of combining
[expressions](\(concepts.expression.anchor)).
[expressions](#\(concepts.expression.anchor)).
"""
}
20 changes: 20 additions & 0 deletions docs/reference/remap/errors.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package metadata

import "strconv"

remap: {
#Error: {
anchor: "\(code)"
binarylogic marked this conversation as resolved.
Show resolved Hide resolved
code: >=100 & <1000 & int
description: string
rationale: string | null
resolution: string
title: string

examples: [remap.#Example, ...remap.#Example]
}

errors: [Code=string]: #Error & {
code: strconv.ParseInt(Code, 0, 8)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package metadata

remap: errors: "100": {
title: "Unhandled root runtime error"
description: """
A root expression is fallible and its [runtime error](\(urls.vrl_runtime_errors)) is not handled.
"""
rationale: """
VRL is [fail-safe](\(urls.vrl_fail_safety)) and requires that all possible runtime errors be handled. This
contributes heavily to VRL's [safety principle](\(urls.vrl_safety)), ensuring that VRL programs are reliable
once deployed.
"""
resolution: """
[Handle](\(urls.vrl_error_handling)) the runtime error by [assigning](\(urls.vrl_error_handling_assigning)),
[coalescing](\(urls.vrl_error_handling_coalescing)), or [raising](\(urls.vrl_error_handling_raising)) the
error.
"""

examples: [
{
"title": "\(title) (assigning)"
source: #"""
get_env_var("HOST")
"""#
raises: compiletime: #"""
error: \#(title)
┌─ :1:1
1 │ (5 / 2)
│ ^^^^^
│ │
│ this expression is unhandled
"""#
diff: #"""
- get_env_var("HOST")
+# .host = get_env_var("HOST")
"""#
},
]
}
41 changes: 41 additions & 0 deletions docs/reference/remap/errors/101_malformed_regex_literal.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package metadata

remap: errors: "101": {
title: "Malformed regex literal"
description: """
A [regex literal expression](\(urls.vrl_expressions)#\(remap.literals.regular_expression.anchor)) is malformed
and does not result in a valid regular expression.
"""
rationale: """
Invalid regular expressions will not compile.
"""
resolution: """
Regular expressions are difficult to write and commonly result in syntax errors. If you're parsing a common
log format then we recommend using one of VRL's [`parse_*` functions](\(urls.vrl_functions)#parsing). If
you do not see a fucntion for your format please [request it](\(urls.new_feature_request)). Otherwise, use the
[Rust regex tester](\(urls.regex_tester)) to test and correct your regular expression.
"""

examples: [
{
"title": "\(title) (common format)"
source: #"""
. |= parse_regex!(.message, r'^(?P<host>[\w\.]+) - (?P<user>[\w]+) (?P<bytes_in>[\d]+) \[?P<timestamp>.*)\] "(?P<method>[\w]+) (?P<path>.*)" (?P<status>[\d]+) (?P<bytes_out>[\d]+)$')
binarylogic marked this conversation as resolved.
Show resolved Hide resolved
"""#
raises: compiletime: #"""
error: \#(title)
┌─ :1:1
1 │ . |= parse_regex(.message, r'^(?P<host>[\w\.]+) - (?P<user>[\w]+) (?P<bytes_in>[\d]+) \[?P<timestamp>.*)\] "(?P<method>[\w]+) (?P<path>.*)" (?P<status>[\d]+) (?P<bytes_out>[\d]+)$')
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│ │
│ this regular expression is invalid
binarylogic marked this conversation as resolved.
Show resolved Hide resolved
"""#
diff: #"""
-. |= parse_regex!(.message, r'^(?P<host>[\w\.]+) - (?P<user>[\w]+) (?P<bytes_in>[\d]+) \[?P<timestamp>.*)\] "(?P<method>[\w]+) (?P<path>.*)" (?P<status>[\d]+) (?P<bytes_out>[\d]+)$')
+. |= parse_common_log!(.message)
"""#
},
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package metadata

remap: errors: "102": {
title: "Non-boolean if expression predicate"
description: """
An [if expression](\(urls.vrl_expressions)#\(remap.literals.regular_expression.anchor)) predicate does not
evaluate to a boolean.
"""
rationale: """
VRL does not implement "truthy" values (non-boolean values that resolve to a boolean, such as `1`) since these
are common foot-guns that can result in unexpected behavior when used in if expressions. This decision
contributes to VRL's [safety principle](\(urls.vrl_safety)), ensuring that VRL programs are reliable once
deployed.
"""
resolution: """
Adjust your if expression predicate to resolve to a boolean. Helpful functions to solve this include
[`exists`](\(urls.vrl_functions)#\(remap.functions.exists.anchor)) and
[`is_nullish`](\(urls.vrl_functions)#\(remap.functions.is_nullish.anchor)).
"""

examples: [
{
"title": "\(title) (strings)"
input: log: message: "key=value"
source: #"""
if .message {
. |= parse_key_value!(.message)
}
"""#
raises: compiletime: #"""
error: \#(title)
┌─ :1:1
1 │ if .message {
│ ^^^^^^^^
│ │
│ if expression predicates must resolve to a strict boolean
"""#
diff: #"""
-if .message {
+if exists(.message) {
. |= parse_key_value!(.message)
}
"""#
},
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package metadata

remap: errors: "103": {
title: "Unhandled assignment runtime error"
description: """
The right-hand side of an [assignment expression](\(urls.vrl_expressions)#\(remap.literals.regular_expression.anchor))
is fallible and can produce a [runtime error](\(urls.vrl_runtime_errors)), but the error is not being
[handled](\(urls.vrl_error_handling)).
"""
rationale: """
VRL is [fail-safe](\(urls.vrl_fail_safety)) and requires that all possible runtime errors be handled. This
contributes heavily to VRL's [safety principle](\(urls.vrl_safety)), ensuring that VRL programs are reliable
once deployed.
"""
resolution: """
[Handle](\(urls.vrl_error_handling)) the runtime error by [assigning](\(urls.vrl_error_handling_assigning)),
[coalescing](\(urls.vrl_error_handling_coalescing)), or [raising](\(urls.vrl_error_handling_raising)) the
error.
"""

examples: [...{
input: log: message: "key=value"
source: #"""
. |= parse_key_value(.message)
"""#
raises: compiletime: #"""
error: \#(title)
┌─ :1:1
1 │ . |= parse_key_value(.message)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│ │
│ This assingment does not handle errors
"""#
}]

examples: [
{
"title": "\(title) (coalescing)"
diff: #"""
-. |= parse_key_value(.message)
+. |= parse_key_value(.message) ?? {}
"""#
},
{
"title": "\(title) (raising)"
diff: #"""
-. |= parse_key_value(.message)
+. |= parse_key_value!(.message)
"""#
},
{
"title": "\(title) (assigning)"
diff: #"""
-. |= parse_key_value(.message)
+., err |= parse_key_value(.message)
"""#
},
]
}
39 changes: 39 additions & 0 deletions docs/reference/remap/errors/104_unneeded_error_assignment.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package metadata

remap: errors: "104": {
title: "Unneeded error assignment"
description: """
The left-hand side of an [assignment expression](\(urls.vrl_expressions)#\(remap.literals.regular_expression.anchor))
needlessly handles errors when the right-hand side _cannot_ fail.
"""
rationale: """
Assigning errors when one is not possible is effectively dead code that makes your program difficult to follow.
Removing the error assignment will simplify your program.
"""
resolution: """
Remove the error assignment.
"""

examples: [
{
"title": "\(title) (strings)"
source: #"""
.message, err = downcase(.message)
"""#
raises: compiletime: #"""
error: \#(title)
┌─ :1:1
1 │ .message, err = downcase(.message)
│ ^^^
│ │
│ unneeded error assignment
"""#
diff: #"""
-.message, err = downcase(.message)
+.message = downcase(.message)
"""#
},
]
}
36 changes: 36 additions & 0 deletions docs/reference/remap/errors/105_undefined_function.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package metadata

remap: errors: "105": {
title: "Undefined function"
description: """
A [function call expression](\(urls.vrl_expressions)#\(remap.literals.regular_expression.anchor)) invokes an
unknown function.
"""
rationale: null
resolution: """
This is typically due to a typo, correcting the function name will resolve this.
"""

examples: [
{
"title": "\(title) (typo)"
source: #"""
parse_keyvalue(.message)
"""#
raises: compiletime: #"""
error: \#(title)
┌─ :1:1
1 │ parse_keyvalue(.message)
│ ^^^^^^^^^^^^^^
│ │
│ Undefined function
"""#
diff: #"""
-parse_keyvalue(.message)
+parse_key_value(.message)
"""#
},
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package metadata

remap: errors: "106": {
title: "Function argument arity mismatch"
description: """
A [function call expression](\(urls.vrl_expressions)#\(remap.literals.regular_expression.anchor)) invokes a
function with too many arguments.
"""
rationale: null
resolution: """
Remove the extra arguments to adhere to the function's documented signature.
"""

examples: [
{
"title": title
source: #"""
parse_json(.message, pretty: true)
"""#
raises: compiletime: #"""
error: \#(title)
┌─ :1:1
1 │ parse_json(.message, pretty: true)
│ ^^^^^^^^^^^^
│ │
│ This argument exceeds the function arity
"""#
diff: #"""
-parse_json(.message, pretty: true)
+parse_json(.message)
"""#
},
]
}
Loading