wrapError wraps underlying keychain failures into a typed *errs.APIError (exit code 1) carrying a hint for troubleshooting keychain access issues. nil and ErrNotFound pass through unchanged.
(op string, err error)
| 32 | // (exit code 1) carrying a hint for troubleshooting keychain access issues. |
| 33 | // nil and ErrNotFound pass through unchanged. |
| 34 | func wrapError(op string, err error) error { |
| 35 | if err == nil || errors.Is(err, ErrNotFound) { |
| 36 | return err |
| 37 | } |
| 38 | |
| 39 | msg := fmt.Sprintf("keychain %s failed: %v", op, err) |
| 40 | hint := "Check if the OS keychain/credential manager is locked or accessible. If running inside a sandbox or CI environment, please ensure the process has the necessary permissions to access the keychain, you can try running this outside the sandbox." |
| 41 | |
| 42 | if errors.Is(err, errNotInitialized) { |
| 43 | hint = "The keychain master key may have been cleaned up or deleted. If running inside a sandbox or CI environment, please ensure the process has the necessary permissions to access the keychain, you can try running this outside the sandbox. Otherwise, please reconfigure the CLI by running lark-cli config init." |
| 44 | } |
| 45 | hint += extraHint(err) |
| 46 | |
| 47 | func() { |
| 48 | defer func() { recover() }() |
| 49 | LogAuthError("keychain", op, fmt.Errorf("keychain %s error: %w", op, err)) |
| 50 | }() |
| 51 | |
| 52 | return errs.NewAPIError(errs.SubtypeUnknown, "%s", msg). |
| 53 | WithHint("%s", hint). |
| 54 | WithCause(err) |
| 55 | } |
| 56 | |
| 57 | // KeychainAccess abstracts keychain Get/Set/Remove for dependency injection. |
| 58 | // Used by AppSecret operations (ForStorage, ResolveSecretInput, RemoveSecretStore). |