Structured error handling with typed error codes for programmatic handling.
All errors returned by this library are instances of CryptoError, which wraps a standard Go error with a typed error code.
type CryptoError struct {
Code ErrorCode
Err error
}
func (e *CryptoError) Error() string // Returns formatted error message
func (e *CryptoError) Unwrap() error // Returns wrapped error| Code | Constant | Description |
|---|---|---|
INVALID_INPUT |
ErrInvalidInput |
Input is not valid |
PASSWORD_REQUIRED |
ErrPasswordRequired |
Password is required but not provided |
KEYFILE_REQUIRED |
ErrKeyfileRequired |
Keyfile is required but not provided |
INVALID_PASSWORD |
ErrInvalidPassword |
Decryption failed due to incorrect password |
INVALID_KEYFILE |
ErrInvalidKeyfile |
Decryption failed due to incorrect keyfile |
INVALID_ENCRYPTED_DATA |
ErrInvalidEncryptedData |
Data is corrupted or not encrypted with this library |
ENCRYPTION_FAILED |
ErrEncryptionFailed |
Encryption operation failed |
DECRYPTION_FAILED |
ErrDecryptionFailed |
Decryption operation failed |
UNSUPPORTED_FORMAT |
ErrUnsupportedFormat |
Encrypted data format is not supported |
Helper function to check if an error matches a specific error code. Works with wrapped errors.
| Parameter | Type | Description |
|---|---|---|
err |
error |
The error to check |
code |
ErrorCode |
The error code to match |
bool - true if the error is a CryptoError with the given code.
import filecrypto "github.com/Time-File/go-file-crypto"
plain, err := filecrypto.Decrypt(encrypted, filecrypto.DecryptOptions{
Password: "wrong-password",
})
if err != nil {
var cryptoErr *filecrypto.CryptoError
if errors.As(err, &cryptoErr) {
fmt.Println(cryptoErr.Code) // "INVALID_PASSWORD"
}
}plain, err := filecrypto.Decrypt(encrypted, filecrypto.DecryptOptions{
Password: "wrong",
})
if err != nil {
if filecrypto.IsCryptoErrorCode(err, filecrypto.ErrInvalidPassword) {
fmt.Println("Wrong password")
}
}plain, err := filecrypto.Decrypt(encrypted, opts)
if err != nil {
var cryptoErr *filecrypto.CryptoError
if errors.As(err, &cryptoErr) {
switch cryptoErr.Code {
case filecrypto.ErrInvalidPassword:
fmt.Println("Incorrect password. Please try again.")
case filecrypto.ErrInvalidKeyfile:
fmt.Println("Invalid keyfile. Please select the correct file.")
case filecrypto.ErrInvalidEncryptedData:
fmt.Println("File is corrupted or not encrypted.")
case filecrypto.ErrKeyfileRequired:
fmt.Println("This file requires a keyfile to decrypt.")
case filecrypto.ErrPasswordRequired:
fmt.Println("This file requires a password to decrypt.")
case filecrypto.ErrUnsupportedFormat:
fmt.Println("Unsupported encryption format.")
default:
fmt.Printf("Error: %s\n", cryptoErr.Error())
}
}
}var errorMessages = map[filecrypto.ErrorCode]string{
filecrypto.ErrInvalidInput: "잘못된 입력입니다.",
filecrypto.ErrPasswordRequired: "비밀번호가 필요합니다.",
filecrypto.ErrKeyfileRequired: "키 파일이 필요합니다.",
filecrypto.ErrInvalidPassword: "비밀번호가 올바르지 않습니다.",
filecrypto.ErrInvalidKeyfile: "키 파일이 올바르지 않습니다.",
filecrypto.ErrInvalidEncryptedData: "손상된 파일입니다.",
filecrypto.ErrEncryptionFailed: "암호화에 실패했습니다.",
filecrypto.ErrDecryptionFailed: "복호화에 실패했습니다.",
filecrypto.ErrUnsupportedFormat: "지원하지 않는 형식입니다.",
}
func localizedError(err error) string {
var cryptoErr *filecrypto.CryptoError
if errors.As(err, &cryptoErr) {
if msg, ok := errorMessages[cryptoErr.Code]; ok {
return msg
}
}
return "알 수 없는 오류입니다."
}// File encrypted with keyfile, but password provided
plain, err := filecrypto.Decrypt(keyfileEncrypted, filecrypto.DecryptOptions{
Password: "test",
})
// err.Code == ErrKeyfileRequired
// File encrypted with password, but keyfile provided
plain, err := filecrypto.Decrypt(passwordEncrypted, filecrypto.DecryptOptions{
KeyData: "base64key",
})
// err.Code == ErrPasswordRequiredplain, err := filecrypto.Decrypt(corruptedData, filecrypto.DecryptOptions{
Password: "test",
})
// err.Code == ErrInvalidEncryptedData or ErrInvalidPasswordStreaming decryption distinguishes between wrong password/keyfile and data corruption:
err := filecrypto.DecryptReader(reader, writer, filecrypto.StreamDecryptOptions{
Password: "wrong",
})
// First chunk fails → ErrInvalidPassword
// Later chunk fails → ErrDecryptionFailed (data corruption)| Error Code | Cause |
|---|---|
ErrInvalidPassword |
First chunk decryption failed (wrong password) |
ErrInvalidKeyfile |
First chunk decryption failed (wrong keyfile) |
ErrDecryptionFailed |
Later chunk decryption failed (data corruption) |