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

[FEATURE REQUEST] Improved developer experience for error handling #648

Closed
elena-kolevska opened this issue Dec 11, 2023 · 4 comments
Closed
Assignees
Labels
help wanted Extra attention is needed kind/enhancement New feature or request waiting-for-runtime-release waiting for runtime RC release before this PR can be tested in CI/CD and merged
Milestone

Comments

@elena-kolevska
Copy link
Contributor

elena-kolevska commented Dec 11, 2023

Describe the feature

Developers would have to do some gymnastics (example below) in their apps in order to get to the error details in the new, richer error model (dapr/dapr#7257). I suggest we add a helper function in the SDK to improve the developer experience, at the very minimum - provide an equivalent of the parse_grpc_error function below.

Here's what developers need to do, currently:

def parse_grpc_error(error):
    if not isinstance(error, grpc.RpcError):
        return None

    error_status = {
        'code': error.code(),
        'message': error.details(),
        'details': []
    }

    # Check if the error has additional details
    if error.trailing_metadata():
        for metadata in error.trailing_metadata():
            if metadata.key == 'grpc-status-details-bin':
                status_proto = status_pb2.Status()
                status_proto.MergeFromString(metadata.value)
                for detail in status_proto.details:
                    any_pb = any_pb2.Any()
                    any_pb.CopyFrom(detail)
                    # You can add specific parsing for known types here
                    error_status['details'].append(any_pb)

    return error_status


with DaprClient() as d:

    storeName = 'statestore1'

    key = "key_1||"
    value = "value_1"

    # Wait for sidecar to be up within 5 seconds.
    d.wait(2)

    # Save single state.
    try:
        d.save_state(store_name=storeName, key=key, value=value)
        print(f"State store has successfully saved {value} with {key} as key")
    except grpc.RpcError as err:
        error_status = parse_grpc_error(err)

        print("Error code: ", error_status['code'])
        print("Error message: ", error_status['message'])

        for detail in error_status['details']:
            detail_any = any_pb2.Any()
            detail_any.CopyFrom(detail)

            # Check and handle each expected type
            if detail_any.Is(error_details_pb2.ErrorInfo.DESCRIPTOR):
                error_info = error_details_pb2.ErrorInfo()
                detail_any.Unpack(error_info)
                print("ErrorInfo:", error_info)
            elif detail_any.Is(error_details_pb2.ResourceInfo.DESCRIPTOR):
                resource_info = error_details_pb2.ResourceInfo()
                detail_any.Unpack(resource_info)
                print("ResourceInfo:", resource_info)
            elif detail_any.Is(error_details_pb2.BadRequest.DESCRIPTOR):
                bad_request = error_details_pb2.BadRequest()
                detail_any.Unpack(bad_request)
                print("BadRequest:", bad_request)
            # Add more elif blocks for other types you expect
            else:
                print("Unknown detail type")

Release Note

RELEASE NOTE: UPDATE Improved developer experience for error handling

@elena-kolevska elena-kolevska added the kind/enhancement New feature or request label Dec 11, 2023
@berndverst
Copy link
Member

The new error model is not merged in runtime yet - so from the SDK perspective it does not exist yet. PRs welcome once there is a runtime RC that contains the new error model.

@berndverst berndverst added help wanted Extra attention is needed waiting-for-runtime-release waiting for runtime RC release before this PR can be tested in CI/CD and merged labels Dec 13, 2023
@berndverst
Copy link
Member

How about a new subclass of type grpc.RpcError with all the convenience methods you need to make it easy to extract standardized Dapr error in a convenient way. This would be the most user friendly.

Of course everywhere in the code such as in save_state() you need to catch the grpc.RpcError and use that to instantiate your new error class. Then throw the new error class instead.

@elena-kolevska
Copy link
Contributor Author

Yes, I was thinking the same. I'll start on it this week.

@elena-kolevska
Copy link
Contributor Author

/assign

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed kind/enhancement New feature or request waiting-for-runtime-release waiting for runtime RC release before this PR can be tested in CI/CD and merged
Projects
None yet
Development

No branches or pull requests

2 participants