in frontend/mux.go [351:415]
func (m *BuildMux) Handle(ctx context.Context, client gwclient.Client) (_ *gwclient.Result, retErr error) {
// Cache the opts in case this is the raw client
// This prevents a grpc request for multiple calls to BuildOpts
opts := client.BuildOpts().Opts
origOpts := dalec.DuplicateMap(opts)
t := opts[keyTarget]
defer func() {
if retErr != nil {
if _, ok := origOpts[keyTopLevelTarget]; !ok {
retErr = errors.Wrapf(retErr, "error handling requested build target %q", t)
// If we have a spec name, load it to make the error message more helpful
spec, _ := m.loadSpec(ctx, client)
if spec != nil && spec.Name != "" {
retErr = errors.Wrapf(retErr, "spec: %s", spec.Name)
}
}
}
}()
ctx = bklog.WithLogger(ctx, bklog.G(ctx).
WithFields(logrus.Fields{
"handlers": maps.Keys(m.handlers),
"target": opts[keyTarget],
"requestid": opts[requestIDKey],
"targetKey": GetTargetKey(client),
}))
bklog.G(ctx).Info("Handling request")
res, handled, err := m.handleSubrequest(ctx, client, opts)
if err != nil {
return nil, err
}
if handled {
return res, nil
}
matched, h, err := m.lookupTarget(ctx, t)
if err != nil {
return nil, err
}
ctx = bklog.WithLogger(ctx, bklog.G(ctx).WithField("matched", matched))
// each call to `Handle` handles the next part of the target
// When we call the handler, we want to remove the part of the target that is being handled so the next handler can handle the next part
client = trimTargetOpt(client, matched)
client = maybeSetDalecTargetKey(client, matched)
res, err = h.f(ctx, client)
if err != nil {
err = injectPathsToNotFoundError(matched, err)
return res, err
}
// If this request was a request to list targets, we need to modify the response a bit
// Otherwise we can just return the result as is.
if opts[requestIDKey] == bktargets.SubrequestsTargetsDefinition.Name {
return m.fixupListResult(matched, res)
}
return res, nil
}