Skip to content

Commit

Permalink
Handle temp table metadata error as user exception and its test
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamVyborny committed Aug 8, 2023
1 parent e67dda1 commit 405d94e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
21 changes: 19 additions & 2 deletions src/Extractor/Adapters/BcpQueryMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,28 @@ public function getColumns(): ColumnCollection
}
return new ColumnCollection($columns);
} catch (Throwable $e) {
throw new BcpAdapterException(
sprintf('DB query "%s" failed: %s', $sql, $e->getMessage()),
throw $this->handleException($e, $sql);
}
}

protected function handleException(Throwable $e, string $sql): Throwable
{
if (strpos($e->getMessage(), 'uses a temp table') !== false) {
preg_match('/\[SQL Server\](.*)/', $e->getMessage(), $matches);
return new UserException(
sprintf(
'Cannot retrieve column metadata via query "%s". %s',
$sql,
$matches[1] ?? $e->getMessage()
),
0,
$e
);
}
return new BcpAdapterException(
sprintf('DB query "%s" failed: %s', $sql, $e->getMessage()),
0,
$e
);
}
}
42 changes: 42 additions & 0 deletions tests/phpunit/ExceptionHandlingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Keboola\DbExtractor\Tests;

use Keboola\DbExtractor\Adapter\Exception\UserException;
use Keboola\DbExtractor\Extractor\Adapters\BcpQueryMetadata;
use Keboola\DbExtractor\Extractor\MSSQLPdoConnection;
use Keboola\DbExtractor\FunctionalTests\PdoTestConnection;
use PDOException;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use ReflectionClass;

class ExceptionHandlingTest extends TestCase
{
public function testBcpQueryMetadataExceptionHandling(): void
{
$this->expectException(UserException::class);
// phpcs:disable Generic.Files.LineLength
$this->expectExceptionMessage("Cannot retrieve column metadata via query \"EXEC sp_describe_first_result_set N'SET NOCOUNT ON EXEC Keboola_propojeni.dbo.IFS_ImportObratovky_All 129; SELECT ''OK'' AS Status', null, 0;\". The metadata could not be determined because statement 'delete from #ErrFile' in procedure 'IFS_ImportObratovky_All' uses a temp table.");
// phpcs:enable Generic.Files.LineLength

$query = "EXEC sp_describe_first_result_set N'SET NOCOUNT ON " .
"EXEC Keboola_propojeni.dbo.IFS_ImportObratovky_All 129; SELECT ''OK'' AS Status', null, 0;";

$object = new BcpQueryMetadata(
new MSSQLPdoConnection(new NullLogger(), PdoTestConnection::createDbConfig()),
$query
);
$method = (new ReflectionClass($object))->getMethod('handleException');
$method->setAccessible(true);
throw $method->invoke(
$object,
new PDOException('SQLSTATE[42000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The ' .
"metadata could not be determined because statement 'delete from #ErrFile' in procedure 'IFS_Import" .
'Obratovky_All\' uses a temp table.'),
$query
);
}
}

0 comments on commit 405d94e

Please sign in to comment.