Skip to content

Error handling

Greg Bowler edited this page Apr 19, 2026 · 1 revision

Base exception

All library-specific exceptions extend GT\Cipher\CipherException.

If we only need one catch block for any Cipher failure, catching that base type is usually enough:

use GT\Cipher\CipherException;

try {
	// encrypt or decrypt here
}
catch(CipherException $exception) {
	// handle all Cipher-specific failures
}

Encryption failures

CipherText throws EncryptionFailureException when encryption cannot be completed.

This generally means libsodium rejected the inputs, such as an invalid key size.

Message decryption failures

EncryptedMessage::decrypt() throws GT\Cipher\Message\DecryptionFailureException when:

  • the cipher text is malformed
  • the key or IV does not match
  • libsodium rejects the inputs

That allows the receiving application to treat the payload as unreadable without exposing any secret detail.

URI decryption failures

EncryptedUri::decryptMessage() throws UriDecryptionFailureException when the URI contains cipher and IV values but decryption still fails.

In practice that often means:

  • the wrong key was used
  • the URI was altered
  • the cipher text was not valid

Missing URI parameters

The EncryptedUri constructor throws MissingQueryStringException when the required cipher or iv parameter is missing or empty.

The exception message contains the missing parameter name, which is useful when responding with validation errors or debugging integration issues.

Working with previous exceptions

Where libsodium throws internally, Cipher wraps the original throwable as the previous exception.

That means application code can log the full exception chain during development while still presenting a cleaner message to the end user.

Typical handling approach

For most applications, the following pattern is enough:

use GT\Cipher\CipherException;

try {
	$plainText = $encryptedUri->decryptMessage($key);
}
catch(CipherException $exception) {
	http_response_code(400);
	echo "The encrypted message could not be read.";
}

That keeps the external response calm and predictable without leaking implementation details.


To see the library running end-to-end, continue to Examples.

Clone this wiki locally