Las excepciones como tal son para eso, para casos excepcionales, no debes de manejar el flujo de tu aplicación usando excepciones, y como dices tú, al usuario solamente le debes de mostrar run mensaje de error y no una excepción.
Dentro de tu flujo de tu frontController debes de manejar un bloque try/catch para las excepciones y guardarlas en un log para su posterior análisis, pero como dice Smolky, para casos que debas de controlar debes de forzosamente regresar alguna información.
Por ejemplo el componente Zend_Auth de Zend, este tiene un método authenticate que puede ser correcto o no dependiendo de la información del usuario, por ejemplo:
Código PHP:
Ver original$result = $auth->authenticate($adapter);
if (!$result->isValid()) {
switch ($result->getCode()) {
case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
// mostrar error
}
}
No devuelves como tal un error si no un objeto result, que puede ser o no válido, para casos como que no tengas un item en la base de datos puedes usar null para verificar, por ejemplo:
Código PHP:
Ver original$item = $model->getItem($id);
if ($item === null) {
// show error message
}
O usar un esquema como el anterior, de devolver un objeto sin datos con un código de error:
Código PHP:
Ver original$item = $model->getItem($id);
if (!$item->isValid()) {
// muestras error
}
Como tal formas de hacerlo hay muchas, todo depende del diseño de tu aplicación y que uses las excepciones para casos excepcionales (por ejemplo que no exista la conexión a la BDD, etc), ese tipo de acciones sí deben de lanzar excepciones que debes de cachar en tu frontController y ya de ahí solo mostrar un error genérico al usuario y enviar una alerta.
Saludos.