Merge branch 'v1.15' into endgame_1.15-updates

This commit is contained in:
Hannah Hunter 2025-01-14 09:09:13 -05:00 committed by GitHub
commit 9f049c39b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 333 additions and 37 deletions

View File

@ -14,6 +14,7 @@ Let's get started using the [conversation API]({{< ref conversation-overview.md
- Set up one of the available Dapr components (echo) that work with the conversation API.
- Add the conversation client to your application.
- Run the connection using `dapr run`.
## Set up the conversation component
@ -35,6 +36,7 @@ spec:
## Connect the conversation client
The following examples use an HTTP client to send a POST request to Dapr's sidecar HTTP endpoint. You can also use [the Dapr SDK client instead]({{< ref "#related-links" >}}).
{{< tabs ".NET" "Go" "Rust" >}}
@ -42,8 +44,30 @@ spec:
<!-- .NET -->
{{% codetab %}}
```dotnet
todo
```csharp
using Dapr.AI.Conversation;
using Dapr.AI.Conversation.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprConversationClient();
var app = builder.Build();
var conversationClient = app.Services.GetRequiredService<DaprConversationClient>();
var response = await conversationClient.ConverseAsync("conversation",
new List<DaprConversationInput>
{
new DaprConversationInput(
"Please write a witty haiku about the Dapr distributed programming framework at dapr.io",
DaprConversationRole.Generic)
});
Console.WriteLine("Received the following from the LLM:");
foreach (var resp in response.Outputs)
{
Console.WriteLine($"\t{resp.Result}");
}
```
{{% /codetab %}}
@ -130,6 +154,84 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
{{< /tabs >}}
## Run the conversation connection
Start the connection using the `dapr run` command. For example, for this scenario, we're running `dapr run` on an application with the app ID `conversation` and pointing to our conversation YAML file in the `./config` directory.
{{< tabs ".NET" "Go" "Rust" >}}
<!-- .NET -->
{{% codetab %}}
```bash
dapr run --app-id conversation --dapr-grpc-port 50001 --log-level debug --resources-path ./config -- dotnet run
```
{{% /codetab %}}
<!-- Go -->
{{% codetab %}}
```bash
dapr run --app-id conversation --dapr-grpc-port 50001 --log-level debug --resources-path ./config -- go run ./main.go
```
**Expected output**
```
- '== APP == conversation output: hello world'
```
{{% /codetab %}}
<!-- Rust -->
{{% codetab %}}
```bash
dapr run --app-id=conversation --resources-path ./config --dapr-grpc-port 3500 -- cargo run --example conversation
```
**Expected output**
```
- 'conversation input: hello world'
- 'conversation output: hello world'
```
{{% /codetab %}}
{{< /tabs >}}
## Related links
Try out the conversation API using the full examples provided in the supported SDK repos.
{{< tabs ".NET" "Go" "Rust" >}}
<!-- .NET -->
{{% codetab %}}
[Dapr conversation example with the .NET SDK](https://github.com/dapr/dotnet-sdk/tree/master/examples/AI/ConversationalAI)
{{% /codetab %}}
<!-- Go -->
{{% codetab %}}
[Dapr conversation example with the Go SDK](https://github.com/dapr/go-sdk/tree/main/examples/conversation)
{{% /codetab %}}
<!-- Rust -->
{{% codetab %}}
[Dapr conversation example with the Rust SDK](https://github.com/dapr/rust-sdk/tree/main/examples/src/conversation)
{{% /codetab %}}
{{< /tabs >}}
## Next steps

View File

@ -203,7 +203,112 @@ As messages are sent to the given message handler code, there is no concept of r
The example below shows the different ways to stream subscribe to a topic.
{{< tabs Go>}}
{{< tabs Python Go >}}
{{% codetab %}}
You can use the `subscribe` method, which returns a `Subscription` object and allows you to pull messages from the stream by calling the `next_message` method. This runs in and may block the main thread while waiting for messages.
```python
import time
from dapr.clients import DaprClient
from dapr.clients.grpc.subscription import StreamInactiveError
counter = 0
def process_message(message):
global counter
counter += 1
# Process the message here
print(f'Processing message: {message.data()} from {message.topic()}...')
return 'success'
def main():
with DaprClient() as client:
global counter
subscription = client.subscribe(
pubsub_name='pubsub', topic='orders', dead_letter_topic='orders_dead'
)
try:
while counter < 5:
try:
message = subscription.next_message()
except StreamInactiveError as e:
print('Stream is inactive. Retrying...')
time.sleep(1)
continue
if message is None:
print('No message received within timeout period.')
continue
# Process the message
response_status = process_message(message)
if response_status == 'success':
subscription.respond_success(message)
elif response_status == 'retry':
subscription.respond_retry(message)
elif response_status == 'drop':
subscription.respond_drop(message)
finally:
print("Closing subscription...")
subscription.close()
if __name__ == '__main__':
main()
```
You can also use the `subscribe_with_handler` method, which accepts a callback function executed for each message received from the stream. This runs in a separate thread, so it doesn't block the main thread.
```python
import time
from dapr.clients import DaprClient
from dapr.clients.grpc._response import TopicEventResponse
counter = 0
def process_message(message):
# Process the message here
global counter
counter += 1
print(f'Processing message: {message.data()} from {message.topic()}...')
return TopicEventResponse('success')
def main():
with (DaprClient() as client):
# This will start a new thread that will listen for messages
# and process them in the `process_message` function
close_fn = client.subscribe_with_handler(
pubsub_name='pubsub', topic='orders', handler_fn=process_message,
dead_letter_topic='orders_dead'
)
while counter < 5:
time.sleep(1)
print("Closing subscription...")
close_fn()
if __name__ == '__main__':
main()
```
[Learn more about streaming subscriptions using the Python SDK client.]({{< ref "python-client.md#streaming-message-subscription" >}})
{{% /codetab %}}
{{% codetab %}}

View File

@ -2,6 +2,6 @@
type: docs
title: "Debugging Dapr applications and the Dapr control plane"
linkTitle: "Debugging"
weight: 50
weight: 60
description: "Guides on how to debug Dapr applications and the Dapr control plane"
---

View File

@ -2,6 +2,6 @@
type: docs
title: "Components"
linkTitle: "Components"
weight: 30
weight: 40
description: "Learn more about developing Dapr's pluggable and middleware components"
---

View File

@ -0,0 +1,8 @@
---
type: docs
title: "Error codes"
linkTitle: "Error codes"
weight: 20
description: "Error codes and messages you may encounter while using Dapr"
---

View File

@ -1,20 +1,11 @@
---
type: docs
title: "Error codes returned by APIs"
linkTitle: "Error codes"
description: "Detailed reference of the Dapr API error codes"
weight: 1400
title: "Error codes reference guide"
linkTitle: "Reference"
description: "List of gRPC and HTTP error codes in Dapr and their descriptions"
weight: 20
---
For http calls made to Dapr runtime, when an error is encountered, an error json is returned in http response body. The json contains an error code and an descriptive error message, e.g.
```
{
"errorCode": "ERR_STATE_GET",
"message": "Requested state key does not exist in state store."
}
```
The following tables list the error codes returned by Dapr runtime:
### Actors API
@ -154,3 +145,8 @@ The following tables list the error codes returned by Dapr runtime:
| ERR_MALFORMED_REQUEST | Error with a malformed request. |
| ERR_MALFORMED_REQUEST_DATA | Error request data is malformed. |
| ERR_MALFORMED_RESPONSE | Error response data is malformed. |
## Next steps
- [Handling HTTP error codes]({{< ref http-error-codes.md >}})
- [Handling gRPC error codes]({{< ref grpc-error-codes.md >}})

View File

@ -0,0 +1,62 @@
---
type: docs
title: "Errors overview"
linkTitle: "Overview"
weight: 10
description: "Overview of Dapr errors"
---
An error code is a numeric or alphamueric code that indicates the nature of an error and, when possible, why it occured.
Dapr error codes are standardized strings for over 80+ common errors across HTTP and gRPC requests when using the Dapr APIs. These codes are both:
- Returned in the JSON response body of the request.
- When enabled, logged in debug-level logs in the runtime.
- If you're running in Kubernetes, error codes are logged in the sidecar.
- If you're running in self-hosted, you can enable and run debug logs.
## Error format
Dapr error codes consist of a prefix, a category, and shorthand of the error itself. For example:
| Prefix | Category | Error shorthand |
| ------ | -------- | --------------- |
| ERR_ | PUBSUB_ | NOT_FOUND |
Some of the most common errors returned include:
- ERR_ACTOR_TIMER_CREATE
- ERR_PURGE_WORKFLOW
- ERR_STATE_STORE_NOT_FOUND
- ERR_HEALTH_NOT_READY
> **Note:** [See a full list of error codes in Dapr.]({{< ref error-codes-reference.md >}})
An error returned for a state store not found might look like the following:
```json
{
"error": "Bad Request",
"error_msg": "{\"errorCode\":\"ERR_STATE_STORE_NOT_FOUND\",\"message\":\"state store <name> is not found\",\"details\":[{\"@type\":\"type.googleapis.com/google.rpc.ErrorInfo\",\"domain\":\"dapr.io\",\"metadata\":{\"appID\":\"nodeapp\"},\"reason\":\"DAPR_STATE_NOT_FOUND\"}]}",
"status": 400
}
```
The returned error includes:
- The error code: `ERR_STATE_STORE_NOT_FOUND`
- The error message describing the issue: `state store <name> is not found`
- The app ID in which the error is occuring: `nodeapp`
- The reason for the error: `DAPR_STATE_NOT_FOUND`
## Dapr error code metrics
Metrics help you see when exactly errors are occuring from within the runtime. Error code metrics are collected using the `error_code_total` endpoint. This endpoint is disabled by default. You can [enable it using the `recordErrorCodes` field in your configuration file]({{< ref "metrics-overview.md#configuring-metrics-for-error-codes" >}}).
## Demo
Watch a demo presented during [Diagrid's Dapr v1.15 celebration](https://www.diagrid.io/videos/dapr-1-15-deep-dive) to see how to enable error code metrics and handle error codes returned in the runtime.
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/NTnwoDhHIcQ?si=I2uCB_TINGxlu-9v&amp;start=2812" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
## Next step
{{< button text="See a list of all Dapr error codes" page="error-codes-reference" >}}

View File

@ -1,20 +1,18 @@
---
type: docs
title: Dapr errors
linkTitle: "Dapr errors"
weight: 700
description: "Information on Dapr errors and how to handle them"
title: Handling gRPC error codes
linkTitle: "gRPC"
weight: 40
description: "Information on Dapr gRPC errors and how to handle them"
---
## Error handling: Understanding errors model and reporting
Initially, errors followed the [Standard gRPC error model](https://grpc.io/docs/guides/error/#standard-error-model). However, to provide more detailed and informative error messages, an enhanced error model has been defined which aligns with the gRPC [Richer error model](https://grpc.io/docs/guides/error/#richer-error-model).
{{% alert title="Note" color="primary" %}}
Not all Dapr errors have been converted to the richer gRPC error model.
{{% /alert %}}
### Standard gRPC Error Model
## Standard gRPC Error Model
The [Standard gRPC error model](https://grpc.io/docs/guides/error/#standard-error-model) is an approach to error reporting in gRPC. Each error response includes an error code and an error message. The error codes are standardized and reflect common error conditions.
@ -25,7 +23,7 @@ ERROR:
Message: input key/keyPrefix 'bad||keyname' can't contain '||'
```
### Richer gRPC Error Model
## Richer gRPC Error Model
The [Richer gRPC error model](https://grpc.io/docs/guides/error/#richer-error-model) extends the standard error model by providing additional context and details about the error. This model includes the standard error `code` and `message`, along with a `details` section that can contain various types of information, such as `ErrorInfo`, `ResourceInfo`, and `BadRequest` details.

View File

@ -0,0 +1,21 @@
---
type: docs
title: "Handling HTTP error codes"
linkTitle: "HTTP"
description: "Detailed reference of the Dapr HTTP error codes and how to handle them"
weight: 30
---
For HTTP calls made to Dapr runtime, when an error is encountered, an error JSON is returned in response body. The JSON contains an error code and an descriptive error message.
```
{
"errorCode": "ERR_STATE_GET",
"message": "Requested state key does not exist in state store."
}
```
## Related
- [Error code reference list]({{< ref error-codes-reference.md >}})
- [Handling gRPC error codes]({{< ref grpc-error-codes.md >}})

View File

@ -2,6 +2,6 @@
type: docs
title: "Integrations"
linkTitle: "Integrations"
weight: 60
weight: 70
description: "Dapr integrations with other technologies"
---

View File

@ -2,6 +2,6 @@
type: docs
title: "Local development"
linkTitle: "Local development"
weight: 40
weight: 50
description: "Capabilities for developing Dapr applications locally"
---

View File

@ -2,7 +2,7 @@
type: docs
title: "Dapr Software Development Kits (SDKs)"
linkTitle: "SDKs"
weight: 20
weight: 30
description: "Use your favorite languages with Dapr"
no_list: true
---

View File

@ -145,9 +145,12 @@ metrics:
- /payments/{paymentID}/refund
- /payments/{paymentID}/details
excludeVerbs: false
recordErrorCodes: true
```
In the examples above, the path filter `/orders/{orderID}/items/{itemID}` would return _a single metric count_ matching all the `orderID`s and all the `itemID`s, rather than multiple metrics for each `itemID`. For more information, see [HTTP metrics path matching]({{< ref "metrics-overview.md#http-metrics-path-matching" >}})
In the examples above, the path filter `/orders/{orderID}/items/{itemID}` would return _a single metric count_ matching all the `orderID`s and all the `itemID`s, rather than multiple metrics for each `itemID`. For more information, see [HTTP metrics path matching]({{< ref "metrics-overview.md#http-metrics-path-matching" >}}).
The above example also enables [recording error code metrics]({{< ref "metrics-overview.md#configuring-metrics-for-error-codes" >}}), which is disabled by default.
The following table lists the properties for metrics:

View File

@ -72,7 +72,7 @@ spec:
## Configuring metrics for error codes
You can enable additional metrics for [Dapr API error codes](https://docs.dapr.io/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. Dapr APIs which communicate back to their caller may return standardized error codes. As described in the [Dapr development docs](https://github.com/dapr/dapr/blob/master/docs/development/dapr-metrics.md), a new metric called `error_code_total` is recorded, which allows monitoring of error codes triggered by application, code, and category. See [the `errorcodes` package](https://github.com/dapr/dapr/blob/master/pkg/messages/errorcodes/errorcodes.go) for specific codes and categories.
You can enable additional metrics for [Dapr API error codes](https://docs.dapr.io/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. Dapr APIs which communicate back to their caller may return standardized error codes. [A new metric called `error_code_total` is recorded]({{< ref errors-overview.md >}}), which allows monitoring of error codes triggered by application, code, and category. See [the `errorcodes` package](https://github.com/dapr/dapr/blob/master/pkg/messages/errorcodes/errorcodes.go) for specific codes and categories.
Example configuration:
```yaml

View File

@ -63,7 +63,7 @@ You must propagate the headers from `service A` to `service B`. For example: `In
##### Pub/sub messages
Dapr generates the trace headers in the published message topic. These trace headers are propagated to any services listening on that topic.
Dapr generates the trace headers in the published message topic. For `rawPayload` messages, it is possible to specify the `traceparent` header to propagate the tracing information. These trace headers are propagated to any services listening on that topic.
#### Propagating multiple different service calls

View File

@ -36,6 +36,7 @@ spec:
labels:
- name: <LABEL-NAME>
regex: {}
recordErrorCodes: <TRUE-OR-FALSE>
latencyDistributionBuckets:
- <BUCKET-VALUE-MS-0>
- <BUCKET-VALUE-MS-1>

@ -1 +1 @@
Subproject commit 03038fa519670b583eabcef1417eacd55c3e44c8
Subproject commit 01b4833474f869865cba916196376fb49a97911c

@ -1 +1 @@
Subproject commit dd9a2d5a3c4481b8a6bda032df8f44f5eaedb370
Subproject commit 2ab3420adc75049bfcf27cb2eeebdc08f2156474

@ -1 +1 @@
Subproject commit 0b7a051b79c7a394e9bd4f57bd40778fb5f29897
Subproject commit 380cda68f82456ecc52cd876e9567a7aaaf4e05f

@ -1 +1 @@
Subproject commit 76866c878a6e79bb889c83f3930172ddb20f1624
Subproject commit 9adc54dedd87846d513943a5ed9ebe0c1627a192

@ -1 +1 @@
Subproject commit 4abf5aa6504f7c0b0018d20f8dc038a486a67e3a
Subproject commit 4e2d3160324f9c5968415acf206c039837df9a63