Verified Commit 80174a6c authored by Lauri Timmanee's avatar Lauri Timmanee
Browse files

Issue #3365480 by ctrlADel, e0ipso, sharkbaitdc, smustgrave, sarahjean,...

Issue #3365480 by ctrlADel, e0ipso, sharkbaitdc, smustgrave, sarahjean, carolpettirossi: [SDC] Improve error handling during prop validation errors
parent 55366658
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
use Drupal\sdc\Exception\InvalidComponentException;
use Drupal\sdc\Plugin\Component;
use Drupal\sdc\Utilities;
use JsonSchema\Constraints\Constraint;
use JsonSchema\Validator;

/**
@@ -164,7 +165,7 @@ public function validateProps(array $context, Component $component): bool {
    $schema = Validator::arrayToObjectRecursive($schema);
    $props = Validator::arrayToObjectRecursive($props_raw);
    $validator = new Validator();
    $validator->validate($props, $schema);
    $validator->validate($props, $schema, Constraint::CHECK_MODE_TYPE_CAST);
    $validator->getErrors();
    if ($validator->isValid()) {
      return TRUE;
@@ -183,7 +184,17 @@ function (array $error) use ($context): bool {
      return TRUE;
    }
    $message_parts = array_map(
      static fn(array $error): string => sprintf("[%s] %s", $error['property'], $error['message']),
      static function (array $error): string {
        // We check the error message instead of values and definitions here
        // because it's hard to access both given the possible complexity of a
        // schema. Since this is a small non critical DX improvement error
        // message checking should be sufficient.
        if (str_contains($error['message'], 'NULL value found, but a ')) {
          $error['message'] .= '. This may be because the property is empty instead of having data present. If possible fix the source data, use the |default() twig filter, or update the schema to allow multiple types.';
        }

        return sprintf("[%s] %s", $error['property'], $error['message']);
      },
      $errors
    );
    $message = implode("/n", $message_parts);
+8 −0
Original line number Diff line number Diff line
$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
name: Array to Object
props:
  type: object
  properties:
    testProp:
      title: 'Needs object'
      type: object
+3 −0
Original line number Diff line number Diff line
<div>
  {{ testProp }}
</div>
+20 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ public function testRender(): void {
    $this->checkIncludeDataMapping();
    $this->checkEmbedWithNested();
    $this->checkPropValidation();
    $this->checkArrayObjectTypeCast();
    $this->checkNonExistingComponent();
    $this->checkLibraryOverrides();
    $this->checkAttributeMerging();
@@ -171,6 +172,25 @@ protected function checkPropValidation(): void {
    }
  }

  /**
   * Ensure fuzzy coercing of arrays and objects works properly.
   */
  protected function checkArrayObjectTypeCast(): void {
    $content = ['test' => []];
    $build = [
      '#type' => 'inline_template',
      '#context' => ['content' => $content],
      '#template' => "{{ include('sdc_test:array-to-object', { testProp: content.test }, with_context = false) }}",
    ];
    try {
      $this->renderComponentRenderArray($build);
      $this->addToAssertionCount(1);
    }
    catch (\Throwable $e) {
      $this->fail('Empty array was not converted to object');
    }
  }

  /**
   * Ensures that including an invalid component creates an error.
   */