Files
suaveplan/packages/identity/auth/macos-keychain/src/errors/keychain-errors.ts
2026-05-27 23:47:53 +01:00

110 lines
3.1 KiB
TypeScript

/**
* Named error factory helpers for `@suaveplan/macos-keychain`.
*
* Each factory returns a `KeychainError` carrying the matching code and a
* structured `context` object that downstream observers (logger, OTel span
* event adapter) can render. Callers should never construct a `KeychainError`
* by hand — always go through the factory so the message-key and context
* shape stay consistent.
*/
import { KEYCHAIN_CODES, KeychainError } from "../error-codes.js";
/** Construct a `KEYCHAIN.NOT_FOUND` error. */
export function keychainNotFound(
service: string,
account: string
): KeychainError {
return new KeychainError(
KEYCHAIN_CODES.NOT_FOUND,
"keychain.error.not_found",
{ context: { service, account } }
);
}
/** Construct a `KEYCHAIN.ITEM_EXISTS` error. */
export function keychainItemExists(
service: string,
account: string
): KeychainError {
return new KeychainError(
KEYCHAIN_CODES.ITEM_EXISTS,
"keychain.error.item_exists",
{ context: { service, account } }
);
}
/** Construct a `KEYCHAIN.ACCESS_FAILED` error. */
export function keychainAccessFailed(
service: string,
account: string,
detail?: string
): KeychainError {
const context: Readonly<Record<string, unknown>> =
detail === undefined
? { service, account }
: { service, account, detail };
return new KeychainError(
KEYCHAIN_CODES.ACCESS_FAILED,
"keychain.error.access_failed",
{ context }
);
}
/** Construct a `KEYCHAIN.LOCKED` error. */
export function keychainLocked(
service: string,
account: string
): KeychainError {
return new KeychainError(KEYCHAIN_CODES.LOCKED, "keychain.error.locked", {
context: { service, account },
});
}
/** Construct a `KEYCHAIN.UNAVAILABLE` error. */
export function keychainUnavailable(detail?: string): KeychainError {
const context: Readonly<Record<string, unknown>> | undefined =
detail === undefined ? undefined : { detail };
return new KeychainError(
KEYCHAIN_CODES.UNAVAILABLE,
"keychain.error.unavailable",
context === undefined ? {} : { context }
);
}
/** Construct a `KEYCHAIN.PERMISSION_DENIED` error. */
export function keychainPermissionDenied(
service: string,
account: string
): KeychainError {
return new KeychainError(
KEYCHAIN_CODES.PERMISSION_DENIED,
"keychain.error.permission_denied",
{ context: { service, account } }
);
}
/** Construct a `KEYCHAIN.ITEM_INVALID` error. */
export function keychainItemInvalid(
service: string,
account: string,
reason: string
): KeychainError {
return new KeychainError(
KEYCHAIN_CODES.ITEM_INVALID,
"keychain.error.item_invalid",
{ context: { service, account, reason } }
);
}
/** Construct a `KEYCHAIN.TIMEOUT` error. */
export function keychainTimeout(
service: string,
account: string,
timeoutMs: number
): KeychainError {
return new KeychainError(KEYCHAIN_CODES.TIMEOUT, "keychain.error.timeout", {
context: { service, account, timeoutMs },
});
}