Skip to content

Latest commit

 

History

History
183 lines (145 loc) · 5.32 KB

File metadata and controls

183 lines (145 loc) · 5.32 KB

Error Handling

Structured error handling with typed error codes for programmatic handling.

CryptoError Type

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

Error Codes

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

IsCryptoErrorCode(err, code)

Helper function to check if an error matches a specific error code. Works with wrapped errors.

Parameters

Parameter Type Description
err error The error to check
code ErrorCode The error code to match

Returns

bool - true if the error is a CryptoError with the given code.


Usage Examples

Basic Error Handling

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"
	}
}

Using IsCryptoErrorCode Helper

plain, err := filecrypto.Decrypt(encrypted, filecrypto.DecryptOptions{
	Password: "wrong",
})
if err != nil {
	if filecrypto.IsCryptoErrorCode(err, filecrypto.ErrInvalidPassword) {
		fmt.Println("Wrong password")
	}
}

Switch Statement Handling

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())
		}
	}
}

i18n (Internationalization)

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 "알 수 없는 오류입니다."
}

Common Error Scenarios

Password vs Keyfile Mismatch

// 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 == ErrPasswordRequired

Corrupted Data

plain, err := filecrypto.Decrypt(corruptedData, filecrypto.DecryptOptions{
	Password: "test",
})
// err.Code == ErrInvalidEncryptedData or ErrInvalidPassword

Streaming Decryption Errors

Streaming 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)