Database: handle more possible datatype exceptions

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16090
This commit is contained in:
Jon Evans 2023-11-15 12:27:25 -05:00
parent 35edd84269
commit 44374c661f
2 changed files with 96 additions and 29 deletions

View File

@ -443,8 +443,17 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
case SQL_REAL:
case SQL_DECIMAL:
case SQL_NUMERIC:
{
try
{
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
}
catch( nanodbc::null_access_error& e )
{
// Column was empty (null)
aResult[column] = std::string();
}
break;
}
@ -540,44 +549,93 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
timer.Stop();
try
auto handleException =
[&]( std::runtime_error& aException, const std::string& aExtraContext = "" )
{
m_lastError = aException.what();
std::string extra = aExtraContext.empty() ? "" : ": " + aExtraContext;
wxLogTrace( traceDatabase,
wxT( "Exception while parsing result %d from SelectAll: %s%s" ),
aResults.size(), m_lastError, extra );
};
while( results.next() )
{
short columnCount = 0;
ROW result;
for( short j = 0; j < results.columns(); ++j )
try
{
std::string column = toUTF8( results.column_name( j ) );
columnCount = results.columns();
}
catch( nanodbc::database_error& e )
{
handleException( e );
return false;
}
switch( results.column_datatype( j ) )
for( short j = 0; j < columnCount; ++j )
{
std::string column;
std::string columnExtraDbgInfo;
int datatype = SQL_UNKNOWN_TYPE;
try
{
column = toUTF8( results.column_name( j ) );
datatype = results.column_datatype( j );
columnExtraDbgInfo = fmt::format( "column index {}, name '{}', type {}", j, column,
datatype );
}
catch( nanodbc::index_range_error& e )
{
handleException( e, columnExtraDbgInfo );
return false;
}
switch( datatype )
{
case SQL_DOUBLE:
case SQL_FLOAT:
case SQL_REAL:
case SQL_DECIMAL:
case SQL_NUMERIC:
{
try
{
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
}
catch( nanodbc::null_access_error& e )
{
// Column was empty (null)
result[column] = std::string();
}
catch( std::runtime_error& e )
{
handleException( e, columnExtraDbgInfo );
return false;
}
break;
}
default:
{
try
{
result[column] = toUTF8( results.get<nanodbc::string>( j,
NANODBC_TEXT( "" ) ) );
}
catch( std::runtime_error& e )
{
handleException( e, columnExtraDbgInfo );
return false;
}
}
}
}
aResults.emplace_back( std::move( result ) );
}
}
catch( nanodbc::database_error& e )
{
m_lastError = e.what();
wxLogTrace( traceDatabase, wxT( "Exception while parsing results from SelectAll: %s" ),
m_lastError );
return false;
}
wxLogTrace( traceDatabase, wxT( "SelectAll from %s completed in %0.1f ms" ), aTable,
timer.msecs() );

View File

@ -551,8 +551,17 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
continue;
}
wxString value( std::any_cast<std::string>( aRow.at( mapping.column ) ).c_str(),
wxConvUTF8 );
std:: string strValue;
try
{
strValue = std::any_cast<std::string>( aRow.at( mapping.column ) );
}
catch( std::bad_any_cast& e )
{
}
wxString value( strValue.c_str(), wxConvUTF8 );
if( mapping.name == wxT( "Value" ) )
{