Все зависит от того, являются ли оба класса вместе частью одного слоя или это взаимодействие между разными слоями.
В первом случае исключения можно объединить одним интерфейсом (или родительским исключением). И на этом обобщенном исключении завязываться в другом слое.
Пример
class FirstException extend ModuleException {}
class SecondException extend ModuleException {}
class ModuleFirst
{
public function work()
{
throw new FirstException('first);
}
}
class ModuleSecond
{
public function work()
{
throw new SecondException('second);
}
}
тогда дальше ловить из слоя можно так
try {
$module->work();
} catch(ModuleException $e) {
// обработка
}
Если взаимодействие между слоями, то оборачивать каждый раз и выбрасывать свое дальше.
Пример
class FirstException {}
class SecondException {}
class ModuleFirst
{
public function work()
{
try {
$module2->work();
} catch(SecondException $e) {
throw new FirstException($e->getMessage, 0, $e);
}
}
}
class ModuleSecond
{
public function work()
{
throw new SecondException('second);
}
}
try {
$module1->work();
} catch(FirstException $e) {
// обработка
}