A couple of things to note: most modules do
not set the variable $! on failure. For example, DBI sets the variable $DBI::errstr for class method errors, and $dbh->errstr for errors concerning a specific database handle. Also, you really have to look at the docs for each module to determine whether a particular method returning undef or false means that the method failed. Generally this will only be true for methods whose return value is specified to have a certain meaning.
Spreadsheet::WriteExcel's write method appears not to be one of them. Finally, you have to be careful because unlike $@, $! is
not guaranteed to contain a blank string or other false value when no error has occurred, so its value is essentially unpredictable in those circumstances. See
perlvar for details.