如何包装try catch或其他错误处理

I'm a little new to OOP in PHP. I was putting together an ip to location code from MaxMind, and wanted to wrap some error handling around it, because if you supply it with an incorrect IP address, or the database is corrupt, it'll throw a fatal error.

Most of my code is stock code, but I cannot get the error handling part correct.

Here's the stock code. The idea here is to set $countryCode = 'UN' and $countryName = 'Unknown' initially, and then, if the script works, set it to whatever depending on the Ip address supplied.

Stock Code

require_once($_SERVER['DOCUMENT_ROOT'].'\vendor\autoload.php');
use GeoIp2\Database\Reader;

$countryCode = 'UN';
$countryName = 'Unknown';

$reader = new Reader($_SERVER['DOCUMENT_ROOT'].'\geoip\GeoLite2-City.mmdb');

$record = $reader->city('24.22.173.253');
$countryCode = $record->country->isoCode . '<br>'; // 'US'
$countryName = $record->country->name . '<br>'; // 'United States'

echo $countryCode;
echo $countryName;

I tried

require_once($_SERVER['DOCUMENT_ROOT'].'\vendor\autoload.php');
use GeoIp2\Database\Reader;

$countryCode = 'UN';
$countryName = 'Unknown';

try{
$reader = new Reader($_SERVER['DOCUMENT_ROOT'].'\geoip\GeoLite2-City.mmdb');
}
catch(Exception $e)
  {
  echo 'Message: ' .$e->getMessage();
  }

$record = $reader->city('24.22.173.253');
$countryCode = $record->country->isoCode . '<br>'; // 'US'
$countryName = $record->country->name . '<br>'; // 'United States'

echo $countryCode;
echo $countryName;

However, this is what I'm trying to do:

require_once($_SERVER['DOCUMENT_ROOT'].'\vendor\autoload.php');
use GeoIp2\Database\Reader;


$countryCode = 'UN';
$countryName = 'Unknown';

**If (the below is successful -> the db is successfully opened)**
$reader = new Reader($_SERVER['DOCUMENT_ROOT'].'\geoip\GeoLite2-City.mmdb');
then (proceed with the below){
$record = $reader->city('24.22.173.253');
$countryCode = $record->country->isoCode . '<br>'; // 'US'
$countryName = $record->country->name . '<br>'; // 'United States'
}
else
//Send an email to the admin here

echo $countryCode;
echo $countryName;

I cant use if() here, how is this done using try catch? In all there's no need to halt the script. Let the default values of $countryCode and $countryName remain if the i[ detect does not succeed.

The code in the MaxMind script is done this way:

if (!filter_var($ipAddress, FILTER_VALIDATE_IP)) {
            throw new \InvalidArgumentException(
                "The value \"$ipAddress\" is not a valid IP address."
            );
        }

If any line within a try block throws an exception, future lines are not ran and the catch block is ran instead. So you can safely move those lines into the try block:

require_once($_SERVER['DOCUMENT_ROOT'].'\vendor\autoload.php');
use GeoIp2\Database\Reader;

$countryCode = 'UN';
$countryName = 'Unknown';

try {
    $reader = new Reader($_SERVER['DOCUMENT_ROOT'].'\geoip\GeoLite2-City.mmdb');
    $record = $reader->city('24.22.173.253');
    $countryCode = $record->country->isoCode . '<br>'; // 'US'
    $countryName = $record->country->name . '<br>'; // 'United States'
} catch(Exception $e) {
    // Send an email to the admin here instead of echo'ing $e->getMessage()
    // if that's what you want to do.
    echo 'Message: ' .$e->getMessage();
}

echo $countryCode;
echo $countryName;

Now, if the first line of the try block throws an exception, the other three lines won't be executed. Instead, the catch block will be executed. So that is where you can send your email to the admin.

(If the $reader = line throws an exception, the $record = line will not be executed, nor will subsequent lines within the try block.)