Skip to content

DataFetcher.processRegions does not forward passAlong to part/layout processors #2255

Description

@sigdestad

Summary

DataFetcher.processRegions() does not forward passAlong when it recurses into region components. As a result, custom values handed to dataFetcher.process() reach page processors but never reach the part and layout processors inside regions — they silently receive undefined.

The types say otherwise, which is what makes this expensive to debug: addPart and addLayout accept the same OVERRIDES generic as addPage, so the code typechecks cleanly and fails only at runtime.

Where

src/main/resources/lib/enonic/react4xp/DataFetcher.ts:453 (master):

private processRegions(component: PageComponent | LayoutComponent): RegionsData {
    ...
            const processedComponent = this.doProcess({
                component: origComponent,     // <-- passAlong not forwarded
            });

processPage and processLayout both destructure ...passAlong and correctly hand it to invokeProcessor for their own processor — but they call this.processRegions(component) without it, so the chain is cut for every descendant. invokeProcessor then injects only the built-ins (dataFetcher, component, content, request, runMode).

Reproduction

// controller
dataFetcher.process({content, request, site, mySiteConfig: getSiteConfig()});

// page processor — mySiteConfig is defined ✅
dataFetcher.addPage('com.example:default', {
    processor: ({mySiteConfig}) => ({ok: !!mySiteConfig})
});

// part processor in a region — mySiteConfig is undefined ❌
dataFetcher.addPart('com.example:my-part', {
    processor: ({mySiteConfig}) => ({ok: !!mySiteConfig})
});

Both typecheck. Only the page processor gets a value.

Affected versions

Present unchanged in every release that ships DataFetcher — verified by diffing the bundled lib/enonic/react4xp/index.js in the published jars for 6.0.0, 6.0.1, 6.1.0, 6.1.1 and 7.0.0. Not a regression; it has never worked.

Impact

Found in production on market.enonic.com. A part processor read searchResultPage from the site config passed along from the controller; it resolved to undefined, the front-page search form rendered with an empty action="", and the browser submitted back to the current page instead of the search results page. Because an empty action is valid HTML and undefined config degraded to '', nothing errored — the search box just quietly stopped working.

Suggested fix

Forward passAlong through the recursion:

private processRegions(component, passAlong) {
    ...
    const processedComponent = this.doProcess({...passAlong, component: origComponent});

with the two call sites in processPage/processLayout updated to this.processRegions(component, passAlong).

If forwarding is not the intended behaviour, then the OVERRIDES generic should be removed from addPart/addLayout so the type system stops promising something the runtime does not deliver — and the limitation documented. Either way the current combination is a trap.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions