|
13 | 13 |
|
14 | 14 | use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
15 | 15 | use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException;
|
| 16 | +use Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException; |
16 | 17 | use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
| 18 | +use Symfony\Component\Serializer\Exception\ExceptionInterface; |
17 | 19 | use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
18 | 20 | use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
19 | 21 | use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
|
@@ -71,7 +73,11 @@ public function dehydrate(MountedComponent $mounted): DehydratedComponent
|
71 | 73 | $frontendPropertyNames[$frontendName] = $name;
|
72 | 74 |
|
73 | 75 | // TODO: improve error message if not readable
|
74 |
| - $value = $this->propertyAccessor->getValue($component, $name); |
| 76 | + try { |
| 77 | + $value = $this->propertyAccessor->getValue($component, $name); |
| 78 | + } catch (UninitializedPropertyException $exception) { |
| 79 | + throw new \LogicException(sprintf('The "%s" property on the "%s" component is uninitialized. Did you forget to pass this into the component?', $name, \get_class($component)), 0, $exception); |
| 80 | + } |
75 | 81 | $dehydratedValue = null;
|
76 | 82 |
|
77 | 83 | if ($method = $liveProp->dehydrateMethod()) {
|
@@ -153,7 +159,24 @@ public function hydrate(object $component, array $data, string $componentName):
|
153 | 159 | } elseif (!$value && $type && $type->allowsNull() && is_a($type->getName(), \BackedEnum::class, true) && !\in_array($value, array_map(fn (\BackedEnum $e) => $e->value, $type->getName()::cases()))) {
|
154 | 160 | $value = null;
|
155 | 161 | } elseif (null !== $value && $type && !$type->isBuiltin()) {
|
156 |
| - $value = $this->normalizer->denormalize($value, $type->getName(), 'json', [self::LIVE_CONTEXT => true]); |
| 162 | + try { |
| 163 | + $value = $this->normalizer->denormalize($value, $type->getName(), 'json', [self::LIVE_CONTEXT => true]); |
| 164 | + } catch (ExceptionInterface $exception) { |
| 165 | + $json = json_encode($value); |
| 166 | + $message = sprintf( |
| 167 | + 'The normalizer was used to hydrate/denormalize the "%s" property on your "%s" live component, but it failed: %s', |
| 168 | + $name, |
| 169 | + \get_class($component), |
| 170 | + $exception->getMessage() |
| 171 | + ); |
| 172 | + |
| 173 | + // unless the data is gigantic, include it in the error to help |
| 174 | + if (\strlen($json) < 1000) { |
| 175 | + $message .= sprintf(' The data sent from the frontend was: %s', $json); |
| 176 | + } |
| 177 | + |
| 178 | + throw new \LogicException($message, 0, $exception); |
| 179 | + } |
157 | 180 | }
|
158 | 181 |
|
159 | 182 | if ($dehydratedComponent->hasExposed($frontendName)) {
|
|
0 commit comments