• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Dawn Errors
2
3Dawn produces errors for several reasons. The most common is validation errors, indicating that a
4given descriptor, configuration, state, or action is not valid according to the WebGPU spec. Errors
5can also be produced during exceptional circumstances such as the system running out of GPU memory
6or the device being lost.
7
8The messages attached to these errors will frequently be one of the primary tools developers use to
9debug problems their applications, so it is important that the messages Dawn returns are useful.
10
11Following the guidelines in document will help ensure that Dawn's errors are clear, informative, and
12consistent.
13
14## Returning Errors
15
16Since errors are expected to be an exceptional case, it's important that code that produces an error
17doesn't adversely impact the performance of the error-free path. The best way to ensure that is to
18make sure that all errors are returned from within an `if` statement that uses the `DAWN_UNLIKELY()`
19macro to indicate that the expression is not expected to evaluate to true. For example:
20
21```C++
22if (DAWN_UNLIKELY(offset > buffer.size)) {
23  return DAWN_VALIDATION_ERROR("Offset (%u) is larger than the size (%u) of %s."
24    offset, buffer.size, buffer);
25}
26```
27
28To simplify producing validation errors, it's strongly suggested that the `DAWN_INVALID_IF()` macro
29is used, which will wrap the expression in the `DAWN_UNLIKELY()` macro for you:
30
31```C++
32// This is equivalent to the previous example.
33DAWN_INVALID_IF(offset > buffer.size, "Offset (%u) is larger than the size (%u) of %s."
34    offset, buffer.size, buffer);
35```
36
37// TODO: Cover `MaybeError`, `ResultOrError<T>`, `DAWN_TRY(_ASSIGN)`, `DAWN_TRY_CONTEXT`, etc...
38
39## Error message formatting
40
41Errors returned from `DAWN_INVALID_IF()` or `DAWN_VALIDATION_ERROR()` should follow these guidelines:
42
43**Write error messages as complete sentences. (First word capitalized, ends with a period, etc.)**
44 * Example: `Command encoding has already finished.`
45 * Instead of: `encoder finished`
46
47**Error messages should be in the present tense.**
48 * Example: `Buffer is not large enough...`
49 * Instead of: `Buffer was not large enough...`
50
51**When possible any values mentioned should be immediately followed in parentheses by the given value.**
52 * Example: `("Array stride (%u) is not...", stride)`
53 * Output: `Array stride (16) is not...`
54
55**When possible any object or descriptors should be represented by the object formatted as a string.**
56 * Example: `("The %s size (%s) is...", buffer, buffer.size)`
57 * Output: `The [Buffer] size (512) is...` or `The [Buffer "Label"] size (512) is...`
58
59**Enum and bitmask values should be formatted as strings rather than integers or hex values.**
60 * Example: `("The %s format (%s) is...", texture, texture.format)`
61 * Output: `The [Texture "Label"] format (TextureFormat::RGBA8Unorm) is...`
62
63**When possible state both the given value and the expected value or limit.**
64 * Example: `("Offset (%u) is larger than the size (%u) of %s.", offset, buffer.size, buffer)`
65 * Output: `Offset (256) is larger than the size (144) of [Buffer "Label"].`
66
67**State errors in terms of what failed, rather than how to satisfy the rule.**
68 * Example: `Binding size (3) is less than the minimum binding size (32).`
69 * Instead of: `Binding size (3) must not be less than the minimum binding size (32).`
70
71**Don't repeat information given in context.**
72 * See next section for details
73
74## Error Context
75
76When calling functions that perform validation consider if calling `DAWN_TRY_CONTEXT()` rather than
77`DAWN_TRY()` is appropriate. Context messages, when provided, will be appended to any validation
78errors as a type of human readable "callstack". An error with context messages appears will be
79formatted as:
80
81```
82<Primary error message.>
83 - While <context message lvl 2>
84 - While <context message lvl 1>
85 - While <context message lvl 0>
86```
87
88For example, if a validation error occurs while validating the creation of a BindGroup, the message
89may be:
90
91```
92Binding size (256) is larger than the size (80) of [Buffer "View Matrix"].
93 - While validating entries[1] as a Buffer
94 - While validating [BindGroupDescriptor "Frame Bind Group"] against [BindGroupLayout]
95 - While calling CreateBindGroup
96```
97
98// TODO: Guidelines about when to include context
99
100## Context message formatting
101
102Context messages should follow these guidelines:
103
104**Begin with the action being taken, starting with a lower case. `- While ` will be appended by Dawn.**
105 * Example: `("validating primitive state")`
106 * Output: `- While validating primitive state`
107
108**When looping through arrays, indicate the array name and index.**
109 * Example: `("validating buffers[%u]", i)`
110 * Output: `- While validating buffers[2]`
111
112**Indicate which descriptors or objects are being examined in as high-level a context as possible.**
113 * Example: `("validating % against %", descriptor, descriptor->layout)`
114 * Output: `- While validating [BindGroupDescriptor "Label"] against [BindGroupLayout]`
115
116**When possible, indicate the function call being made as the top-level context, as well as the parameters passed.**
117 * Example: `("calling %s.CreatePipelineLayout(%s).", this, descriptor)`
118 * Output: `- While calling [Device].CreatePipelineLayout([PipelineLayoutDescriptor]).`
119