Added an eval{} call around Database->query()'s ->prepare() DBI call to better handle lost database handle.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 3 years ago
parent 9eec6c4977
commit 65dfc22a38
  1. 26
      Anvil/Tools/Database.pm
  2. 2
      share/words.xml
  3. 3
      tools/anvil-daemon

@ -803,7 +803,7 @@ sub configure_pgsql
# Make sure we have an entry in our own anvil.conf. # Make sure we have an entry in our own anvil.conf.
my $local_uuid = $anvil->Database->get_local_uuid(); my $local_uuid = $anvil->Database->get_local_uuid();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { local_uuid => $local_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { local_uuid => $local_uuid }});
# If we didn't get the $local_uuid, then there is no entry for this system in anvil.conf yet, so we'll add it. # If we didn't get the $local_uuid, then there is no entry for this system in anvil.conf yet, so we'll add it.
if (not $local_uuid) if (not $local_uuid)
@ -15393,12 +15393,27 @@ sub query
} }
# Do the query. # Do the query.
my $DBreq = $anvil->data->{cache}{database_handle}{$uuid}->prepare($query) or $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0075", variables => { local $@;
my $DBreq = eval { $anvil->data->{cache}{database_handle}{$uuid}->prepare($query) or $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0075", variables => {
query => (not $secure) ? $query : $anvil->Log->is_secure($query), query => (not $secure) ? $query : $anvil->Log->is_secure($query),
server => $say_server, server => $say_server,
db_error => $DBI::errstr, db_error => $DBI::errstr,
}}); };
if ($@)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0675", variables => {
query => (not $secure) ? $query : $anvil->Log->is_secure($query),
server => $say_server,
eval_error => $@,
}}); }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { DBreq => $DBreq }}); return("!!error!!");
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid,
query => (not $secure) ? $query : $anvil->Log->is_secure($query),
say_server => $say_server,
DBreq => $DBreq,
}});
# Execute on the query # Execute on the query
$DBreq->execute() or $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0076", variables => { $DBreq->execute() or $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0076", variables => {
@ -15667,6 +15682,7 @@ sub resync_databases
### to avoid trouble with primary/foreign keys. ### to avoid trouble with primary/foreign keys.
# We're going to use the array of tables assembles by _find_behind_databases() stored in # We're going to use the array of tables assembles by _find_behind_databases() stored in
# 'sys::database::check_tables' # 'sys::database::check_tables'
my $start_time = time;
foreach my $table (@{$anvil->data->{sys}{database}{check_tables}}) foreach my $table (@{$anvil->data->{sys}{database}{check_tables}})
{ {
# We don't sync 'states' as it's transient and sometimes per-DB. # We don't sync 'states' as it's transient and sometimes per-DB.
@ -16117,6 +16133,10 @@ sub resync_databases
$anvil->data->{sys}{database}{resync_needed} = 0; $anvil->data->{sys}{database}{resync_needed} = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'sys::database::resync_needed' => $anvil->data->{sys}{database}{resync_needed} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'sys::database::resync_needed' => $anvil->data->{sys}{database}{resync_needed} }});
my $time_taken = time - $start_time;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { time_taken => $time_taken }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0674", variables => { took => $time_taken }});
return(0); return(0);
} }

@ -2064,6 +2064,8 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0671">The host: [#!variable!host_name!#] was powered off for an unknown reason, and 'feature::scancore::disable::boot-unknown-stop' is set to: [#!data!feature::scancore::disable::boot-unknown-stop!#]. Will not boot this host.</key> <key name="log_0671">The host: [#!variable!host_name!#] was powered off for an unknown reason, and 'feature::scancore::disable::boot-unknown-stop' is set to: [#!data!feature::scancore::disable::boot-unknown-stop!#]. Will not boot this host.</key>
<key name="log_0672">The host: [#!variable!host_name!#] was powered off for an unknown reason, and 'feature::scancore::disable::boot-unknown-stop' is set to: [#!data!feature::scancore::disable::boot-unknown-stop!#]. If power and temperature looks good, we'll boot it.</key> <key name="log_0672">The host: [#!variable!host_name!#] was powered off for an unknown reason, and 'feature::scancore::disable::boot-unknown-stop' is set to: [#!data!feature::scancore::disable::boot-unknown-stop!#]. If power and temperature looks good, we'll boot it.</key>
<key name="log_0673">The host: [#!variable!host_name!#] has good power and temperature readings. Booting it back up now.</key> <key name="log_0673">The host: [#!variable!host_name!#] has good power and temperature readings. Booting it back up now.</key>
<key name="log_0674">The resync has completed in: [#!variable!took!#] second(s).</key>
<key name="log_0675"><![CDATA[[ Error ] - There was a database handle error while preparing the database query: [#!variable!query!#] on: [#!variable!server!#]. The eval error was: [#!variable!eval_error!#]. Note that if the query reports '--', the query was listed as containing sensitive data and '$anvil->Log->secure' is not set. ]]></key>
<!-- Messages for users (less technical than log entries), though sometimes used for logs, too. --> <!-- Messages for users (less technical than log entries), though sometimes used for logs, too. -->
<key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key> <key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>

@ -92,7 +92,6 @@ $anvil->System->_check_anvil_conf();
# Connect to the database(s). If we have no connections, we'll proceed anyway as one of the 'run_once' tasks # Connect to the database(s). If we have no connections, we'll proceed anyway as one of the 'run_once' tasks
# is to setup the database server. # is to setup the database server.
$anvil->Database->connect({ $anvil->Database->connect({
debug => 2,
check_if_configured => 1, check_if_configured => 1,
check_for_resync => 1, check_for_resync => 1,
}); });
@ -109,7 +108,7 @@ if (not $anvil->data->{sys}{database}{connections})
prep_database($anvil); prep_database($anvil);
# Try connecting again # Try connecting again
$anvil->Database->connect({debug => 2, check_if_configured => 1, check_for_resync => 1}); $anvil->Database->connect({check_if_configured => 1, check_for_resync => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0132"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections}) if (not $anvil->data->{sys}{database}{connections})
{ {

Loading…
Cancel
Save