Skip to content

Commit 11b80c4

Browse files
authored
website: Enhance diagnostics page with references to diag.New functions and more examples (#687)
Reference: #675
1 parent 3635f4f commit 11b80c4

File tree

1 file changed

+98
-9
lines changed

1 file changed

+98
-9
lines changed

website/docs/plugin/framework/diagnostics.mdx

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ working with diagnostics, using functionality from the available
4848

4949
### Severity
5050

51-
`Severity` specifies whether the diagnostic is an error or a warning.
51+
`Severity` specifies whether the diagnostic is an error or a warning. Terraform, nor the framework, supports other severity levels. Use [logging](/terraform/plugin/log/writing) for debugging or informational purposes.
5252

5353
- An **error** will be displayed to the practitioner and halt Terraform's
5454
execution, not continuing to apply changes to later resources in the graph.
@@ -245,12 +245,55 @@ func (s exampleType) Validate(ctx context.Context, in tftypes.Value, path path.P
245245
// ... further logic ...
246246
```
247247
248-
#### Custom Diagnostics Types
248+
### Consistent Diagnostic Creation
249249
250-
Advanced provider developers may need to further differentiate or store
251-
additional data in error and warning types. The
252-
[`diag.Diagnostic` type](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag#Diagnostic)
253-
is an interface type that can be implemented with these methods:
250+
Create a helper function in your provider code using the diagnostic creation functions available in the [`diag` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag) to generate consistent diagnostics for types of errors/warnings. It is also possible to use [custom diagnostics types](#custom-diagnostics-types) to accomplish this same goal.
251+
252+
The [`diag` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag) provides these functions to create various diagnostics:
253+
254+
| Function | Description |
255+
|---|---|
256+
| [`diag.NewAttributeErrorDiagnostic()`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag#NewAttributeErrorDiagnostic) | Create a new error diagnostic with a [path](/terraform/plugin/framework/handling-data/paths). |.
257+
| [`diag.NewAttributeWarningDiagnostic()`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag#NewAttributeWarningDiagnostic) | Create a new warning diagnostic with a [path](/terraform/plugin/framework/handling-data/paths). |.
258+
| [`diag.NewErrorDiagnostic()`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag#NewErrorDiagnostic) | Create a new error diagnostic without a [path](/terraform/plugin/framework/handling-data/paths). |.
259+
| [`diag.NewWarningDiagnostic()`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag#NewWarningDiagnostic) | Create a new warning diagnostic without a [path](/terraform/plugin/framework/handling-data/paths). |.
260+
261+
In this example, the provider code is setup to always convert `error` returns from the API SDK to a consistent error diagnostic.
262+
263+
```go
264+
func APIErrorDiagnostic(err error) diag.Diagnostic {
265+
return diag.NewErrorDiagnostic(
266+
"Unexpected API Error",
267+
"While calling the API, an unexpected error was returned in the response. "+
268+
"Please contact support if you are unsure how to resolve the error.\n\n"+
269+
"Error: "+err.Error(),
270+
)
271+
}
272+
```
273+
274+
This enables calling code in the provider, such as:
275+
276+
```go
277+
func (r ThingResource) Read(ctx context.Context, req resource.ReadRequest, resp resource.ReadResponse) {
278+
// ... other logic ...
279+
280+
apiResp, err := examplesdk.Read(/* ... */) // example API SDK call that may return an error
281+
282+
if err != nil {
283+
resp.Diagnostics.Append(APIErrorDiagnostic(err))
284+
285+
return
286+
}
287+
288+
// ... further logic ...
289+
}
290+
```
291+
292+
## Custom Diagnostics Types
293+
294+
Advanced provider developers may want to store additional data in diagnostics for other logic or create custom diagnostics that include specialized logic.
295+
296+
The [`diag.Diagnostic` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag#Diagnostic) that can be implemented with these methods:
254297
255298
```go
256299
type Diagnostic interface {
@@ -261,13 +304,59 @@ type Diagnostic interface {
261304
}
262305
```
263306
264-
To also include attribute path information, the
265-
[`diag.DiagnosticWithPath` type](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag#DiagnosticWithPath)
266-
can be implemented with the additional `Path()` method:
307+
To also include attribute path information, the [`diag.DiagnosticWithPath` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/diag#DiagnosticWithPath) can be implemented with the additional `Path()` method:
267308
268309
```go
269310
type DiagnosticWithPath interface {
270311
Diagnostic
271312
Path() path.Path
272313
}
273314
```
315+
316+
In this example, a custom diagnostic type stores an underlying `error` that caused the diagnostic:
317+
318+
```go
319+
// UnderlyingErrorDiagnostic is an error diagnostic
320+
// which also stores the underlying error.
321+
type UnderlyingErrorDiagnostic struct {
322+
Detail string
323+
Summary string
324+
UnderlyingError error
325+
}
326+
327+
func (d UnderlyingErrorDiagnostic) Detail() string {
328+
return d.Detail
329+
}
330+
331+
func (d UnderlyingErrorDiagnostic) Equal(o SpecialDiagnostic) bool {
332+
if d.Detail() != o.Detail() {
333+
return false
334+
}
335+
336+
if d.Summary() != o.Summary() {
337+
return false
338+
}
339+
340+
if d.UnderlyingError == nil {
341+
return o.UnderlyingError == nil
342+
}
343+
344+
if o.UnderlyingError == nil {
345+
return false
346+
}
347+
348+
if d.UnderlyingError.Error() != o.UnderlyingError.Error() {
349+
return false
350+
}
351+
352+
return true
353+
}
354+
355+
func (d UnderlyingErrorDiagnostic) Severity() diag.Severity {
356+
return diag.SeverityError
357+
}
358+
359+
func (d UnderlyingErrorDiagnostic) Summary() string {
360+
return d.Summary
361+
}
362+
```

0 commit comments

Comments
 (0)