Skip to content

Commit eefb049

Browse files
authored
Merge pull request #11 from nuxtifyts/refactor/exceptions-usage
Refactor serialization logic and reorganize contracts.
2 parents a1b9726 + ae0bbff commit eefb049

16 files changed

+449
-268
lines changed

clover.xml

Lines changed: 256 additions & 188 deletions
Large diffs are not rendered by default.

src/Concerns/BaseData.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ final public static function from(mixed $value): static
5454
$value = static::normalizeValue($value, static::class);
5555

5656
if ($value === false) {
57-
throw new DeserializeException(
58-
code: DeserializeException::INVALID_VALUE_ERROR_CODE
59-
);
57+
throw DeserializeException::invalidValue();
6058
}
6159

6260
/** @var ClassContext<static> $context */
@@ -73,7 +71,7 @@ classContext: $context,
7371
? static::instanceWithConstructorCallFrom($context, $data)
7472
: static::instanceWithoutConstructorFrom($context, $data);
7573
} catch (Throwable $e) {
76-
throw new DeserializeException($e->getMessage(), $e->getCode(), $e);
74+
throw DeserializeException::generic($e);
7775
}
7876
}
7977

@@ -111,9 +109,7 @@ protected static function instanceWithConstructorCallFrom(ClassContext $context,
111109
$propertyContext = $context->properties[$paramName] ?? null;
112110

113111
if (!$propertyContext) {
114-
throw new DeserializeException(
115-
"Could not find property context for constructor param: $paramName"
116-
);
112+
throw DeserializeException::invalidParamsPassed();
117113
}
118114

119115
$args[$paramName] = $propertyContext->deserializeFrom($value);
@@ -145,7 +141,7 @@ final public function jsonSerialize(): array
145141

146142
return $serializedData;
147143
} catch (Throwable $e) {
148-
throw new SerializeException($e->getMessage(), $e->getCode(), $e);
144+
throw SerializeException::generic($e);
149145
}
150146
}
151147

src/Contexts/PropertyContext.php

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,29 +194,28 @@ public function deserializeFrom(array $value): mixed
194194
}
195195
}
196196

197-
throw new DeserializeException('Could not deserialize value for property: ' . $this->propertyName);
197+
throw DeserializeException::generic();
198198
}
199199

200200
/**
201201
* @return array<string, mixed>
202202
*
203203
* @throws SerializeException
204-
* @throws UnknownTypeException
205204
*/
206205
public function serializeFrom(object $object): array
207206
{
208-
foreach ($this->serializers() as $serializer) {
209-
try {
210-
$serializedData = $serializer->serialize($this, $object);
211-
} catch (SerializeException) {
207+
try {
208+
foreach ($this->serializers() as $serializer) {
209+
try {
210+
$serializedData = $serializer->serialize($this, $object);
211+
} catch (SerializeException) {
212+
}
212213
}
213-
}
214214

215-
if (empty($serializedData)) {
216-
throw new SerializeException('Could not serialize value for property: ' . $this->propertyName);
217-
}
215+
if (empty($serializedData)) {
216+
throw new Exception();
217+
}
218218

219-
try {
220219
if ($this->cipherConfig) {
221220
return array_map(
222221
fn (mixed $value) => $this->cipherConfig->dataCipherClass::cipher(
@@ -229,8 +228,8 @@ public function serializeFrom(object $object): array
229228
}
230229

231230
return $serializedData;
232-
} catch (Exception) {
233-
throw new SerializeException('Could not serialize value for property: ' . $this->propertyName);
231+
} catch (Exception $e) {
232+
throw SerializeException::generic($e);
234233
}
235234
}
236235

src/DataRefiners/DateTimeRefiner.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function refine(mixed $value, PropertyContext $property): mixed
4545
$typeContexts = $property->getFilteredTypeContexts(Type::DATETIME);
4646

4747
if (empty($typeContexts)) {
48-
throw InvalidRefiner::from($this, $property);
48+
throw InvalidRefiner::emptyTypeContexts();
4949
}
5050

5151
$refinedValue = false;

src/Exceptions/DeserializeException.php

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,86 @@
77

88
class DeserializeException extends Exception
99
{
10-
public const int GENERIC_ERROR_CODE = 0;
11-
public const int INVALID_VALUE_ERROR_CODE = 1;
12-
public const int NO_SERIALIZERS_ERROR_CODE = 2;
13-
14-
public function __construct(
15-
string $message = 'Failed to deserialize data',
16-
int $code = self::GENERIC_ERROR_CODE,
17-
?Throwable $previous = null
18-
) {
19-
parent::__construct($message, $code, $previous);
10+
protected const int GENERIC_ERROR_CODE = 0;
11+
protected const int INVALID_VALUE_ERROR_CODE = 1;
12+
protected const int PROPERTY_IS_NOT_NULLABLE_ERROR_CODE = 2;
13+
protected const int UNABLE_TO_DESERIALIZE_SCALAR_TYPE_ITEM_ERROR_CODE = 3;
14+
protected const int UNABLE_TO_DESERIALIZE_BACKED_ENUM_ITEM_ERROR_CODE = 4;
15+
protected const int UNABLE_TO_DESERIALIZE_DATE_TIME_ITEM_ERROR_CODE = 5;
16+
protected const int UNABLE_TO_DESERIALIZE_DATA_ITEM_ERROR_CODE = 6;
17+
protected const int UNABLE_TO_DESERIALIZE_ARRAY_ITEM_ERROR_CODE = 7;
18+
protected const int INVALID_PARAMS_PASSED_ERROR_CODE = 8;
19+
20+
public static function generic(?Throwable $throwable = null): self
21+
{
22+
return new self(
23+
message: 'An error occurred while deserializing data',
24+
code: self::GENERIC_ERROR_CODE,
25+
previous: $throwable
26+
);
27+
}
28+
29+
public static function invalidValue(): self
30+
{
31+
return new self(
32+
message: 'Invalid value passed to from method',
33+
code: self::INVALID_VALUE_ERROR_CODE
34+
);
35+
}
36+
37+
public static function propertyIsNotNullable(): self
38+
{
39+
return new self(
40+
message: 'Property is not nullable',
41+
code: self::PROPERTY_IS_NOT_NULLABLE_ERROR_CODE
42+
);
43+
}
44+
45+
public static function unableToDeserializeScalarTypeItem(): self
46+
{
47+
return new self(
48+
message: 'Could not deserialize scalar type item',
49+
code: self::UNABLE_TO_DESERIALIZE_SCALAR_TYPE_ITEM_ERROR_CODE
50+
);
51+
}
52+
53+
public static function unableToDeserializeBackedEnumItem(): self
54+
{
55+
return new self(
56+
message: 'Could not deserialize BackedEnum item',
57+
code: self::UNABLE_TO_DESERIALIZE_BACKED_ENUM_ITEM_ERROR_CODE
58+
);
59+
}
60+
61+
public static function unableToDeserializeDateTimeItem(): self
62+
{
63+
return new self(
64+
message: 'Could not deserialize DateTime item',
65+
code: self::UNABLE_TO_DESERIALIZE_DATE_TIME_ITEM_ERROR_CODE
66+
);
67+
}
68+
69+
public static function unableToDeserializeDataItem(): self
70+
{
71+
return new self(
72+
message: 'Could not deserialize Data item',
73+
code: self::UNABLE_TO_DESERIALIZE_DATA_ITEM_ERROR_CODE
74+
);
75+
}
76+
77+
public static function unableToDeserializeArrayItem(): self
78+
{
79+
return new self(
80+
message: 'Could not deserialize array item',
81+
code: self::UNABLE_TO_DESERIALIZE_ARRAY_ITEM_ERROR_CODE
82+
);
83+
}
84+
85+
public static function invalidParamsPassed(): self
86+
{
87+
return new self(
88+
message: 'Invalid params passed',
89+
code: self::INVALID_PARAMS_PASSED_ERROR_CODE
90+
);
2091
}
2192
}

src/Exceptions/InvalidRefiner.php

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,13 @@
88

99
class InvalidRefiner extends Exception
1010
{
11-
public static function from(
12-
DataRefiner $refiner,
13-
PropertyContext $property
14-
): self {
11+
protected const int EMPTY_TYPE_CONTEXTS_CODE = 1;
12+
13+
public static function emptyTypeContexts(): self
14+
{
1515
return new self(
16-
sprintf(
17-
'Refiner %s is not applicable to property %s',
18-
get_class($refiner),
19-
$property->propertyName
20-
)
16+
'Property does not have any type contexts',
17+
self::EMPTY_TYPE_CONTEXTS_CODE
2118
);
2219
}
2320
}

src/Exceptions/SerializeException.php

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,60 @@
77

88
class SerializeException extends Exception
99
{
10-
public const int GENERIC_ERROR_CODE = 0;
11-
public const int NO_SERIALIZERS_ERROR_CODE = 1;
12-
13-
public function __construct(
14-
string $message = "",
15-
int $code = 0,
16-
?Throwable $previous = null
17-
) {
18-
parent::__construct($message, $code, $previous);
10+
protected const int GENERIC_ERROR_CODE = 0;
11+
protected const int NO_SERIALIZERS_ERROR_CODE = 1;
12+
protected const int UNABLE_TO_SERIALIZE_SCALAR_TYPE_ITEM_ERROR_CODE = 2;
13+
protected const int UNABLE_TO_SERIALIZE_BACKED_ENUM_ERROR_CODE = 3;
14+
protected const int UNABLE_TO_SERIALIZE_DATE_TIME_ITEM_ERROR_CODE = 4;
15+
protected const int UNABLE_TO_SERIALIZE_DATA_ITEM_ERROR_CODE = 5;
16+
protected const int UNABLE_TO_SERIALIZE_ARRAY_ITEM_ERROR_CODE = 6;
17+
18+
public static function generic(?Throwable $throwable = null): self
19+
{
20+
return new self(
21+
message: 'An error occurred while serializing data',
22+
code: self::GENERIC_ERROR_CODE,
23+
previous: $throwable
24+
);
25+
}
26+
27+
public static function unableToSerializeScalarTypeItem(): self
28+
{
29+
return new self(
30+
message: 'Could not serialize scalar type item',
31+
code: self::UNABLE_TO_SERIALIZE_SCALAR_TYPE_ITEM_ERROR_CODE
32+
);
33+
}
34+
35+
public static function unableToSerializeBackedEnumItem(): self
36+
{
37+
return new self(
38+
message: 'Could not serialize array of BackedEnum items',
39+
code: self::UNABLE_TO_SERIALIZE_BACKED_ENUM_ERROR_CODE
40+
);
41+
}
42+
43+
public static function unableToSerializeDateTimeItem(): self
44+
{
45+
return new self(
46+
message: 'Could not serialize array of DateTime items',
47+
code: self::UNABLE_TO_SERIALIZE_DATE_TIME_ITEM_ERROR_CODE
48+
);
49+
}
50+
51+
public static function unableToSerializeDataItem(): self
52+
{
53+
return new self(
54+
message: 'Could not serialize array of data items',
55+
code: self::UNABLE_TO_SERIALIZE_DATA_ITEM_ERROR_CODE
56+
);
57+
}
58+
59+
public static function unableToSerializeArrayItem(): self
60+
{
61+
return new self(
62+
message: 'Could not serialize array of items',
63+
code: self::UNABLE_TO_SERIALIZE_ARRAY_ITEM_ERROR_CODE
64+
);
1965
}
2066
}

src/Serializers/ArraySerializer.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
namespace Nuxtifyts\PhpDto\Serializers;
44

5+
use Exception;
56
use Nuxtifyts\PhpDto\Contexts\PropertyContext;
67
use Nuxtifyts\PhpDto\Enums\Property\Type;
7-
use Nuxtifyts\PhpDto\Contracts\SerializesArrayOfItems as SerializesArrayOfItemsContract;
88
use Nuxtifyts\PhpDto\Exceptions\DeserializeException;
99
use Nuxtifyts\PhpDto\Exceptions\SerializeException;
10-
use Exception;
10+
use Nuxtifyts\PhpDto\Serializers\Contracts\SerializesArrayOfItems;
1111

1212
class ArraySerializer extends Serializer
1313
{
@@ -20,6 +20,8 @@ public static function supportedTypes(): array
2020

2121
/**
2222
* @return ?array<array-key, mixed>
23+
*
24+
* @throws SerializeException
2325
*/
2426
protected function serializeItem(mixed $item, PropertyContext $property, object $object): ?array
2527
{
@@ -32,7 +34,7 @@ protected function serializeItem(mixed $item, PropertyContext $property, object
3234
try {
3335
foreach ($typeContext->subTypeSerializers() as $serializer) {
3436
try {
35-
if ($serializer instanceof SerializesArrayOfItemsContract) {
37+
if ($serializer instanceof SerializesArrayOfItems) {
3638
$serializedValue = $serializer->serializeArrayOfItems($property, $object);
3739

3840
if (array_key_exists($property->propertyName, $serializedValue)) {
@@ -47,11 +49,13 @@ protected function serializeItem(mixed $item, PropertyContext $property, object
4749
}
4850
}
4951

50-
throw new SerializeException('Could not serialize array of items');
52+
throw SerializeException::unableToSerializeArrayItem();
5153
}
5254

5355
/**
5456
* @return ?array<array-key, mixed>
57+
*
58+
* @throws DeserializeException
5559
*/
5660
protected function deserializeItem(mixed $item, PropertyContext $property): ?array
5761
{
@@ -60,7 +64,7 @@ protected function deserializeItem(mixed $item, PropertyContext $property): ?arr
6064
try {
6165
foreach ($typeContext->subTypeSerializers() as $serializer) {
6266
try {
63-
if ($serializer instanceof SerializesArrayOfItemsContract) {
67+
if ($serializer instanceof SerializesArrayOfItems) {
6468
// @phpstan-ignore-next-line
6569
return $serializer->deserializeArrayOfItems($property, $item);
6670
}
@@ -74,6 +78,6 @@ protected function deserializeItem(mixed $item, PropertyContext $property): ?arr
7478

7579
return is_null($item) && $property->isNullable
7680
? null
77-
: throw new DeserializeException('Property is not nullable');
81+
: throw DeserializeException::unableToDeserializeArrayItem();
7882
}
7983
}

0 commit comments

Comments
 (0)