grpcproxy: return error to client during watch create
Now returns errors from checkPermissionForWatch() via the CancelReason
field. This allows clients to understand why the watch was canceled.
Additionally, this change protects a watch from starting and that
otherwise might hang indefinitely.
@@ -229,11 +229,14 @@ func (wps *watchProxyStream) recvLoop() error {
case *pb.WatchRequest_CreateRequest:
cr := uv.CreateRequest
- if err = wps.checkPermissionForWatch(cr.Key, cr.RangeEnd); err != nil && err == rpctypes.ErrPermissionDenied {
- // Return WatchResponse which is caused by permission checking if and only if
- // the error is permission denied. For other errors (e.g. timeout or connection closed),
- // the permission checking mechanism should do nothing for preserving error code.
- wps.watchCh <- &pb.WatchResponse{Header: &pb.ResponseHeader{}, WatchId: -1, Created: true, Canceled: true}
+ if err := wps.checkPermissionForWatch(cr.Key, cr.RangeEnd); err != nil {
+ wps.watchCh <- &pb.WatchResponse{
+ Header: &pb.ResponseHeader{},
+ WatchId: -1,
+ Created: true,
+ Canceled: true,
+ CancelReason: err.Error(),
+ }
continue
}
