go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/swarming/server/rpcs/tasks_get_result.go (about) 1 // Copyright 2023 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package rpcs 16 17 import ( 18 "context" 19 20 "google.golang.org/grpc/codes" 21 "google.golang.org/grpc/status" 22 23 "go.chromium.org/luci/common/errors" 24 "go.chromium.org/luci/common/logging" 25 "go.chromium.org/luci/gae/service/datastore" 26 27 apipb "go.chromium.org/luci/swarming/proto/api_v2" 28 "go.chromium.org/luci/swarming/server/acls" 29 "go.chromium.org/luci/swarming/server/model" 30 ) 31 32 // GetResult implents the GetResult RPC. 33 func (*TasksServer) GetResult(ctx context.Context, req *apipb.TaskIdWithPerfRequest) (*apipb.TaskResultResponse, error) { 34 if req.TaskId == "" { 35 return nil, status.Errorf(codes.InvalidArgument, "task_id is required") 36 } 37 trKey, err := model.TaskIDToRequestKey(ctx, req.TaskId) 38 if err != nil { 39 return nil, status.Errorf(codes.InvalidArgument, "task_id %s: %s", req.TaskId, err) 40 } 41 trs := &model.TaskResultSummary{Key: model.TaskResultSummaryKey(ctx, trKey)} 42 err = datastore.Get(ctx, trs) 43 switch { 44 case errors.Is(err, datastore.ErrNoSuchEntity): 45 return nil, status.Errorf(codes.NotFound, "no such task") 46 case err != nil: 47 logging.Errorf(ctx, "Error fetching TaskResultSummary %s: %s", req.TaskId, err) 48 return nil, status.Errorf(codes.Internal, "datastore error fetching the task") 49 } 50 res := State(ctx).ACL.CheckTaskPerm(ctx, trs.TaskAuthInfo(), acls.PermTasksGet) 51 if !res.Permitted { 52 return nil, res.ToGrpcErr() 53 } 54 resp := trs.ToProto() 55 if req.IncludePerformanceStats { 56 ps, err := trs.PerformanceStats(ctx) 57 if err != nil { 58 // To preserve the same behavior as the python implementation, if there is an error, 59 // it will get logged, and do not attach PerformanceStats to the response. 60 logging.Errorf(ctx, "Error fetching PerformanceStats for task %s: %s", req.TaskId, err) 61 } else { 62 resp.PerformanceStats = ps 63 } 64 } 65 return resp, nil 66 }