Yes, that is how it works (there's no point in catching the exception inside set_number because set_number is using the exception to signal failure to calling code).
To make it a bit nicer, you could use Exception::Class::TryCatch in tandem with Exception::Class -
use Exception::Class::TryCatch;
...
# try
eval { $obj->some_method('foo') };
# catch
if ( catch my $err ) {
$err->isa('Bio::Phylo::Exceptions::BadNumber') and do { handle_this(
+$err) };
$err->isa('Bio::Phylo::Exceptions::ObjectMismatch') and do { handle_
+that($err) };
}