Repository: containerd/containerd
File: internal/cri/server/restart.go (Go)

Code before:
			}
			return nil
		})
	}
	if err := eg.Wait(); err != nil {
		return err
	}

	// Recover sandboxes in the new SandboxStore
	storedSandboxes, err := c.client.SandboxStore().List(ctx)
	if err != nil {
		return fmt.Errorf("failed to list sandboxes from API: %w", err)
	}
	for _, sbx := range storedSandboxes {
		if _, err := c.sandboxStore.Get(sbx.ID); err == nil {
			continue
		}

		metadata := sandboxstore.Metadata{}
		err := sbx.GetExtension(podsandbox.MetadataKey, &metadata)
		if err != nil {
			if errors.Is(err, errdefs.ErrNotFound) {
				err = c.client.SandboxStore().Delete(ctx, sbx.ID)
				if err != nil {
					return fmt.Errorf("failed to delete sandbox from store: %w", err)
				}
				// TODO: cleanup network namespace
				continue
			}
			return fmt.Errorf("failed to get metadata for stored sandbox %q: %w", sbx.ID, err)
		}

		var (
			state    = sandboxstore.StateUnknown
			endpoint sandboxstore.Endpoint
		)

		status, err := c.sandboxService.SandboxStatus(ctx, sbx.Sandboxer, sbx.ID, false)
		if err != nil {
			log.G(ctx).
				WithError(err).
				WithField("sandbox", sbx.ID).
				Error("failed to recover sandbox state")

			if errdefs.IsNotFound(err) {
				state = sandboxstore.StateNotReady
			}
		} else {
			endpoint.Version = status.Version
			endpoint.Address = status.Address
			if code, ok := runtime.PodSandboxState_value[status.State]; ok {

Review comment (bug):
```suggestion
					return fmt.Errorf("failed to delete sandbox in response to missing metadata for sandbox %q: %w", sbx.ID, err)
```

%q should be used for the sandbox id, not %w, and also this error format is consistent with other errors below.

Code after:
			}
			return nil
		})
	}
	if err := eg.Wait(); err != nil {
		return err
	}

	// Recover sandboxes in the new SandboxStore
	storedSandboxes, err := c.client.SandboxStore().List(ctx)
	if err != nil {
		return fmt.Errorf("failed to list sandboxes from API: %w", err)
	}
	for _, sbx := range storedSandboxes {
		if _, err := c.sandboxStore.Get(sbx.ID); err == nil {
			continue
		}

		metadata := sandboxstore.Metadata{}
		err := sbx.GetExtension(podsandbox.MetadataKey, &metadata)
		if err != nil {
			if errors.Is(err, errdefs.ErrNotFound) {
				log.G(ctx).WithError(err).Errorf("failed to get metadata for stored sandbox %q", sbx.ID)
				// Since commit https://github.com/containerd/containerd/pull/11612 has been merged metadata may not be nil.
				// Before 1162 we should delete leaked sandbox from sandbox store to make sure containerd can start successfully.
				err = c.client.SandboxStore().Delete(ctx, sbx.ID)
				if err != nil {
					log.G(ctx).WithError(err).Errorf("failed to delete sandbox %q, in response to failure to retrieve metadata for sandbox", sbx.ID)
				}
				continue
			}
			return fmt.Errorf("failed to get metadata for stored sandbox %q: %w", sbx.ID, err)
		}

		var (
			state    = sandboxstore.StateUnknown
			endpoint sandboxstore.Endpoint
		)

		status, err := c.sandboxService.SandboxStatus(ctx, sbx.Sandboxer, sbx.ID, false)
		if err != nil {
			log.G(ctx).
				WithError(err).
				WithField("sandbox", sbx.ID).
				Error("failed to recover sandbox state")

			if errdefs.IsNotFound(err) {
				state = sandboxstore.StateNotReady
			}
		} else {
			endpoint.Version = status.Version