Browse Source

fix(core): Fix indexing of long descriptions in postgres

Fixes #745
Michael Bromley 4 years ago
parent
commit
9efd7db288

+ 46 - 0
packages/core/e2e/default-search-plugin.e2e-spec.ts

@@ -883,6 +883,52 @@ describe('Default search plugin', () => {
                     { productId: 'T_3', enabled: false },
                 ]);
             });
+
+            // https://github.com/vendure-ecommerce/vendure/issues/745
+            it('very long Product descriptions no not cause indexing to fail', async () => {
+                // We generate this long string out of random chars because Postgres uses compression
+                // when storing the string value, so e.g. a long series of a single character will not
+                // reproduce the error.
+                const description = Array.from({ length: 220 })
+                    .map(() => Math.random().toString(36))
+                    .join(' ');
+
+                const { createProduct } = await adminClient.query<
+                    CreateProduct.Mutation,
+                    CreateProduct.Variables
+                >(CREATE_PRODUCT, {
+                    input: {
+                        translations: [
+                            {
+                                languageCode: LanguageCode.en,
+                                name: 'Very long description aabbccdd',
+                                slug: 'very-long-description',
+                                description,
+                            },
+                        ],
+                    },
+                });
+                await adminClient.query<CreateProductVariants.Mutation, CreateProductVariants.Variables>(
+                    CREATE_PRODUCT_VARIANTS,
+                    {
+                        input: [
+                            {
+                                productId: createProduct.id,
+                                sku: 'VLD01',
+                                price: 100,
+                                translations: [
+                                    { languageCode: LanguageCode.en, name: 'Very long description variant' },
+                                ],
+                            },
+                        ],
+                    },
+                );
+                await awaitRunningJobs(adminClient);
+                const result = await doAdminSearchQuery({ term: 'aabbccdd' });
+                expect(result.search.items.map(i => i.productName)).toEqual([
+                    'Very long description aabbccdd',
+                ]);
+            });
         });
 
         // https://github.com/vendure-ecommerce/vendure/issues/609

+ 15 - 2
packages/core/src/plugin/default-search-plugin/indexer/indexer.controller.ts

@@ -330,7 +330,7 @@ export class IndexerController {
                             slug: productTranslation.slug,
                             productId: variant.product.id,
                             productName: productTranslation.name,
-                            description: productTranslation.description,
+                            description: this.constrainDescription(productTranslation.description),
                             productVariantName: variantTranslation.name,
                             productAssetId: variant.product.featuredAsset
                                 ? variant.product.featuredAsset.id
@@ -377,7 +377,7 @@ export class IndexerController {
             slug: productTranslation.slug,
             productId: product.id,
             productName: productTranslation.name,
-            description: productTranslation.description,
+            description: this.constrainDescription(productTranslation.description),
             productVariantName: productTranslation.name,
             productAssetId: product.featuredAsset?.id ?? null,
             productPreviewFocalPoint: product.featuredAsset?.focalPoint ?? null,
@@ -444,4 +444,17 @@ export class IndexerController {
         })) as any[];
         await this.queue.push(() => this.connection.getRepository(SearchIndexItem).delete(compositeKeys));
     }
+
+    /**
+     * Prevent postgres errors from too-long indices
+     * https://github.com/vendure-ecommerce/vendure/issues/745
+     */
+    private constrainDescription(description: string): string {
+        const { type } = this.connection.rawConnection.options;
+        const isPostgresLike = type === 'postgres' || type === 'aurora-data-api-pg' || type === 'cockroachdb';
+        if (isPostgresLike) {
+            return description.substring(0, 2600);
+        }
+        return description;
+    }
 }