diff --git a/go/vt/vtadmin/api.go b/go/vt/vtadmin/api.go index cdd7fac76a8..5d02491a4c2 100644 --- a/go/vt/vtadmin/api.go +++ b/go/vt/vtadmin/api.go @@ -154,7 +154,7 @@ func (api *API) FindSchema(ctx context.Context, req *vtadminpb.FindSchemaRequest span.Annotate("table", req.Table) - clusters, _ := api.getClustersForRequest(req.ClusterIds) + clusters, clusterIDs := api.getClustersForRequest(req.ClusterIds) var ( m sync.Mutex @@ -217,7 +217,10 @@ func (api *API) FindSchema(ctx context.Context, req *vtadminpb.FindSchemaRequest switch len(results) { case 0: - return nil, fmt.Errorf("%w: no schemas found with table named %s", errors.ErrNoSchema, req.Table) + return nil, &errors.NoSuchSchema{ + Clusters: clusterIDs, + Table: req.Table, + } case 1: return results[0], nil default: @@ -404,12 +407,24 @@ func (api *API) GetSchema(ctx context.Context, req *vtadminpb.GetSchemaRequest) return nil, fmt.Errorf("%w: no cluster with id %s", errors.ErrUnsupportedCluster, req.ClusterId) } - return c.GetSchema(ctx, req.Keyspace, cluster.GetSchemaOptions{ + schema, err := c.GetSchema(ctx, req.Keyspace, cluster.GetSchemaOptions{ BaseRequest: &vtctldatapb.GetSchemaRequest{ Tables: []string{req.Table}, }, TableSizeOptions: req.TableSizeOptions, }) + if err != nil { + return nil, err + } + + if schema == nil || len(schema.TableDefinitions) == 0 { + return nil, &errors.NoSuchSchema{ + Clusters: []string{req.ClusterId}, + Table: req.Table, + } + } + + return schema, nil } // GetSchemas is part of the vtadminpb.VTAdminServer interface. diff --git a/go/vt/vtadmin/errors/errors.go b/go/vt/vtadmin/errors/errors.go index 58c9cb104dd..b403c8e240c 100644 --- a/go/vt/vtadmin/errors/errors.go +++ b/go/vt/vtadmin/errors/errors.go @@ -35,9 +35,6 @@ var ( // ErrInvalidRequest occurs when a request is invalid for any reason. // For example, if mandatory parameters are undefined. ErrInvalidRequest = errors.New("Invalid request") - // ErrNoSchema occurs when a schema definition cannot be found for a given - // set of filter criteria. - ErrNoSchema = errors.New("no such schema") // ErrNoServingTablet occurs when a tablet with state SERVING cannot be // found for a given set of filter criteria. It is a more specific form of // ErrNoTablet diff --git a/go/vt/vtadmin/errors/typed_error.go b/go/vt/vtadmin/errors/typed_error.go index eec521990c7..defc3058fef 100644 --- a/go/vt/vtadmin/errors/typed_error.go +++ b/go/vt/vtadmin/errors/typed_error.go @@ -18,6 +18,7 @@ package errors import ( "fmt" + "net/http" "strings" ) @@ -77,3 +78,29 @@ func (e *MissingParams) Error() string { func (e *MissingParams) Code() string { return "missing params" } func (e *MissingParams) Details() interface{} { return nil } func (e *MissingParams) HTTPStatus() int { return 400 } + +// NoSuchSchema is returned when a schema definition cannot be found for a given +// set of filter criteria. Both GetSchema and FindSchema can return this error. +type NoSuchSchema struct { + Clusters []string + Table string +} + +func (e *NoSuchSchema) Error() string { + return fmt.Sprintf("%s: no schemas found with table named %s", e.Code(), e.Table) +} + +func (e *NoSuchSchema) Details() interface{} { + details := map[string]interface{}{ + "table": e.Table, + } + + if e.Clusters != nil { + details["clusters"] = e.Clusters + } + + return details +} + +func (e *NoSuchSchema) Code() string { return "no such schema" } +func (e *NoSuchSchema) HTTPStatus() int { return http.StatusNotFound }