func()

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
}