From 4a10788c378d85b1c517f5ff84d2f732ce7652ee Mon Sep 17 00:00:00 2001 From: mamazu <14860264+mamazu@users.noreply.github.com> Date: Tue, 1 Jul 2025 17:45:18 +0200 Subject: [PATCH 1/3] Adding context information when requesting invalid column type --- src/Schema/AbstractSchemaManager.php | 8 ++++- src/Types/Exception/UnknownColumnType.php | 35 +++++++++++++++---- .../Types/Exception/UnknownColumnTypeTest.php | 33 +++++++++++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 tests/Types/Exception/UnknownColumnTypeTest.php diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index b9afdb4ebef..857f70c6924 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -7,6 +7,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception\DatabaseRequired; +use Doctrine\DBAL\Types\Exception\UnknownColumnType; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\Exception\NotSupported; use Doctrine\DBAL\Result; @@ -23,6 +24,7 @@ use function count; use function func_get_arg; use function func_num_args; +use function sprintf; use function strtolower; /** @@ -812,7 +814,11 @@ protected function _getPortableTableColumnList(string $table, string $database, { $list = []; foreach ($rows as $row) { - $column = $this->_getPortableTableColumnDefinition($row); + try { + $column = $this->_getPortableTableColumnDefinition($row); + } catch (UnknownColumnType $unknownTypeException) { + throw UnknownColumnType::withContext($unknownTypeException->getType(), sprintf('table %s', $table)); + } $name = strtolower($column->getQuotedName($this->platform)); $list[$name] = $column; diff --git a/src/Types/Exception/UnknownColumnType.php b/src/Types/Exception/UnknownColumnType.php index 5397f808b71..b53c3e59504 100644 --- a/src/Types/Exception/UnknownColumnType.php +++ b/src/Types/Exception/UnknownColumnType.php @@ -5,24 +5,45 @@ namespace Doctrine\DBAL\Types\Exception; use Exception; +use Throwable; use function sprintf; final class UnknownColumnType extends Exception implements TypesException { - public static function new(string $name): self - { - return new self( - sprintf( - 'Unknown column type "%s" requested. Any Doctrine type that you use has ' + private function __construct( + private string $requestedType, + ?string $context, + int $code = 0, + ?Throwable $throwable = null, + ) { + $message = sprintf( + 'Unknown column type "%s" requested%s. Any Doctrine type that you use has ' . 'to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the ' . 'known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database ' . 'introspection then you might have forgotten to register all database types for a Doctrine Type. ' . 'Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement ' . 'Type#getMappedDatabaseTypes(). If the type name is empty you might ' . 'have a problem with the cache or forgot some mapping information.', - $name, - ), + $this->requestedType, + $context !== null ? ' for ' . $context : '', ); + + parent::__construct($message, $code, $throwable); + } + + public function getType(): string + { + return $this->requestedType; + } + + public static function new(string $name): self + { + return new self($name, null); + } + + public static function withContext(string $name, string $context): self + { + return new self($name, $context); } } diff --git a/tests/Types/Exception/UnknownColumnTypeTest.php b/tests/Types/Exception/UnknownColumnTypeTest.php new file mode 100644 index 00000000000..69101725eea --- /dev/null +++ b/tests/Types/Exception/UnknownColumnTypeTest.php @@ -0,0 +1,33 @@ +getType()); + self::assertStringContainsString( + 'Unknown column type "custom_type" requested.', + $exception->getMessage(), + ); + } + + public function testWithContext(): void + { + $exception = UnknownColumnType::withContext('custom_type', 'table "some_table"'); + + self::assertSame('custom_type', $exception->getType()); + self::assertStringContainsString( + 'Unknown column type "custom_type" requested for table "some_table".', + $exception->getMessage(), + ); + } +} From 9caaba343ec982da1174f89209914560e9a17013 Mon Sep 17 00:00:00 2001 From: mamazu <14860264+mamazu@users.noreply.github.com> Date: Sun, 17 Aug 2025 23:48:20 +0200 Subject: [PATCH 2/3] Removing the bc break --- src/Schema/AbstractSchemaManager.php | 5 +- src/Types/Exception/UnknownColumnType.php | 53 +++++++++++-------- .../Types/Exception/UnknownColumnTypeTest.php | 6 +-- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index 857f70c6924..ef1ce562b45 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -7,13 +7,13 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception\DatabaseRequired; -use Doctrine\DBAL\Types\Exception\UnknownColumnType; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\Exception\NotSupported; use Doctrine\DBAL\Result; use Doctrine\DBAL\Schema\Exception\TableDoesNotExist; use Doctrine\DBAL\Schema\Name\Parsers; use Doctrine\DBAL\Types\Exception\TypesException; +use Doctrine\DBAL\Types\Exception\UnknownColumnType; use Doctrine\Deprecations\Deprecation; use Throwable; @@ -24,7 +24,6 @@ use function count; use function func_get_arg; use function func_num_args; -use function sprintf; use function strtolower; /** @@ -817,7 +816,7 @@ protected function _getPortableTableColumnList(string $table, string $database, try { $column = $this->_getPortableTableColumnDefinition($row); } catch (UnknownColumnType $unknownTypeException) { - throw UnknownColumnType::withContext($unknownTypeException->getType(), sprintf('table %s', $table)); + throw UnknownColumnType::newWithContext($unknownTypeException->getRequestedType(), $table); } $name = strtolower($column->getQuotedName($this->platform)); diff --git a/src/Types/Exception/UnknownColumnType.php b/src/Types/Exception/UnknownColumnType.php index b53c3e59504..dbed8dc9af4 100644 --- a/src/Types/Exception/UnknownColumnType.php +++ b/src/Types/Exception/UnknownColumnType.php @@ -5,45 +5,52 @@ namespace Doctrine\DBAL\Types\Exception; use Exception; -use Throwable; use function sprintf; final class UnknownColumnType extends Exception implements TypesException { - private function __construct( - private string $requestedType, - ?string $context, - int $code = 0, - ?Throwable $throwable = null, - ) { - $message = sprintf( - 'Unknown column type "%s" requested%s. Any Doctrine type that you use has ' + private string $requestedType; + + public function getRequestedType(): string + { + return $this->requestedType; + } + + public static function new(string $name): self + { + $object = new self(sprintf( + 'Unknown column type "%s" requested. Any Doctrine type that you use has ' . 'to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the ' . 'known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database ' . 'introspection then you might have forgotten to register all database types for a Doctrine Type. ' . 'Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement ' . 'Type#getMappedDatabaseTypes(). If the type name is empty you might ' . 'have a problem with the cache or forgot some mapping information.', - $this->requestedType, - $context !== null ? ' for ' . $context : '', - ); + $name, + )); - parent::__construct($message, $code, $throwable); - } + $object->requestedType = $name; - public function getType(): string - { - return $this->requestedType; + return $object; } - public static function new(string $name): self + public static function newWithContext(string $name, string $tableName): self { - return new self($name, null); - } + $object = new self(sprintf( + 'Unknown column type "%s" requested for table "%s". Any Doctrine type that you use has ' + . 'to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the ' + . 'known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database ' + . 'introspection then you might have forgotten to register all database types for a Doctrine Type. ' + . 'Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement ' + . 'Type#getMappedDatabaseTypes(). If the type name is empty you might ' + . 'have a problem with the cache or forgot some mapping information.', + $name, + $tableName, + )); - public static function withContext(string $name, string $context): self - { - return new self($name, $context); + $object->requestedType = $name; + + return $object; } } diff --git a/tests/Types/Exception/UnknownColumnTypeTest.php b/tests/Types/Exception/UnknownColumnTypeTest.php index 69101725eea..91b41b29938 100644 --- a/tests/Types/Exception/UnknownColumnTypeTest.php +++ b/tests/Types/Exception/UnknownColumnTypeTest.php @@ -13,7 +13,7 @@ public function testNew(): void { $exception = UnknownColumnType::new('custom_type'); - self::assertSame('custom_type', $exception->getType()); + self::assertSame('custom_type', $exception->getRequestedType()); self::assertStringContainsString( 'Unknown column type "custom_type" requested.', $exception->getMessage(), @@ -22,9 +22,9 @@ public function testNew(): void public function testWithContext(): void { - $exception = UnknownColumnType::withContext('custom_type', 'table "some_table"'); + $exception = UnknownColumnType::newWithContext('custom_type', 'some_table'); - self::assertSame('custom_type', $exception->getType()); + self::assertSame('custom_type', $exception->getRequestedType()); self::assertStringContainsString( 'Unknown column type "custom_type" requested for table "some_table".', $exception->getMessage(), From 92d7814cd34ba97a143cfb5e10734d6b588eef7f Mon Sep 17 00:00:00 2001 From: mamazu <14860264+mamazu@users.noreply.github.com> Date: Mon, 18 Aug 2025 00:18:58 +0200 Subject: [PATCH 3/3] Adding tests for unknown colum type --- src/Schema/AbstractSchemaManager.php | 6 +++++- src/Types/Exception/UnknownColumnType.php | 16 ++++++++++------ tests/Schema/ColumnEditorTest.php | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index ef1ce562b45..e1c998d93f1 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -816,7 +816,11 @@ protected function _getPortableTableColumnList(string $table, string $database, try { $column = $this->_getPortableTableColumnDefinition($row); } catch (UnknownColumnType $unknownTypeException) { - throw UnknownColumnType::newWithContext($unknownTypeException->getRequestedType(), $table); + throw UnknownColumnType::newWithContext( + $unknownTypeException->getRequestedType(), + $table, + $unknownTypeException, + ); } $name = strtolower($column->getQuotedName($this->platform)); diff --git a/src/Types/Exception/UnknownColumnType.php b/src/Types/Exception/UnknownColumnType.php index dbed8dc9af4..4624f21b0f6 100644 --- a/src/Types/Exception/UnknownColumnType.php +++ b/src/Types/Exception/UnknownColumnType.php @@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Types\Exception; use Exception; +use Throwable; use function sprintf; @@ -35,19 +36,22 @@ public static function new(string $name): self return $object; } - public static function newWithContext(string $name, string $tableName): self + public static function newWithContext(string $name, string $tableName, ?Throwable $previous): self { - $object = new self(sprintf( - 'Unknown column type "%s" requested for table "%s". Any Doctrine type that you use has ' + $object = new self( + sprintf( + 'Unknown column type "%s" requested for table "%s". Any Doctrine type that you use has ' . 'to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the ' . 'known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database ' . 'introspection then you might have forgotten to register all database types for a Doctrine Type. ' . 'Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement ' . 'Type#getMappedDatabaseTypes(). If the type name is empty you might ' . 'have a problem with the cache or forgot some mapping information.', - $name, - $tableName, - )); + $name, + $tableName, + ), + previous: $previous, + ); $object->requestedType = $name; diff --git a/tests/Schema/ColumnEditorTest.php b/tests/Schema/ColumnEditorTest.php index 3ca067c412e..01635af44c7 100644 --- a/tests/Schema/ColumnEditorTest.php +++ b/tests/Schema/ColumnEditorTest.php @@ -7,6 +7,7 @@ use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Exception\InvalidColumnDefinition; use Doctrine\DBAL\Schema\Name\UnqualifiedName; +use Doctrine\DBAL\Types\Exception\UnknownColumnType; use Doctrine\DBAL\Types\IntegerType; use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Types; @@ -78,4 +79,17 @@ public function testTypeNotSet(): void $editor->create(); } + + public function testInvalidType(): void + { + $this->expectException(UnknownColumnType::class); + $this->expectExceptionMessage('Unknown column type "unknown_type"'); + + Column::editor() + ->setUnquotedName('column_char') + ->setTypeName('unknown_type') + ->setFixed(true) + ->setLength(2) + ->create(); + } }