@@ -485,7 +485,12 @@ function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName
485485 }
486486 if ( receivedType . dimension !== expectedType . dimension ) {
487487 if ( receivedType . dimension !== 1 ) {
488- FES . userError ( 'type error' , `You have returned a vector with ${ receivedType . dimension } components in ${ hookName } when a ${ expectedType . baseType + expectedType . dimension } was expected!` ) ;
488+ const receivedTypeDisplay = receivedType . baseType + ( receivedType . dimension > 1 ? receivedType . dimension : '' ) ;
489+ const expectedTypeDisplay = expectedType . baseType + expectedType . dimension ;
490+ FES . userError ( 'type error' ,
491+ `You have returned a ${ receivedTypeDisplay } in ${ hookName } when a ${ expectedTypeDisplay } was expected!\n\n` +
492+ `Make sure your hook returns the correct type.`
493+ ) ;
489494 }
490495 else {
491496 const result = build . primitiveConstructorNode ( strandsContext , expectedType , returned ) ;
@@ -576,7 +581,24 @@ export function createShaderHooksFunctions(strandsContext, fn, shader) {
576581 if ( retNode instanceof StrandsNode ) {
577582 const returnedNode = getNodeDataFromID ( strandsContext . dag , retNode . id ) ;
578583 if ( returnedNode . baseType !== expectedStructType . typeName ) {
579- FES . userError ( "type error" , `You have returned a ${ retNode . baseType } from ${ hookType . name } when a ${ expectedStructType . typeName } was expected.` ) ;
584+ const receivedTypeName = returnedNode . baseType || 'undefined' ;
585+ const receivedDim = dag . dimensions [ retNode . id ] ;
586+ const receivedTypeDisplay = receivedDim > 1 ?
587+ `${ receivedTypeName } ${ receivedDim } ` : receivedTypeName ;
588+
589+ const expectedProps = expectedStructType . properties
590+ . map ( p => p . name ) . join ( ', ' ) ;
591+ FES . userError ( 'type error' ,
592+ `You have returned a ${ receivedTypeDisplay } from ${ hookType . name } when a ${ expectedStructType . typeName } was expected.\n\n` +
593+ `The ${ expectedStructType . typeName } struct has these properties: { ${ expectedProps } }\n\n` +
594+ `Instead of returning a different type, you should modify and return the ${ expectedStructType . typeName } struct that was passed to your hook.\n\n` +
595+ `For example:\n` +
596+ `${ hookType . name } ((inputs) => {\n` +
597+ ` // Modify properties of inputs\n` +
598+ ` inputs.someProperty = ...;\n` +
599+ ` return inputs; // Return the modified struct\n` +
600+ `})`
601+ ) ;
580602 }
581603 const newDeps = returnedNode . dependsOn . slice ( ) ;
582604 for ( let i = 0 ; i < expectedStructType . properties . length ; i ++ ) {
@@ -595,10 +617,14 @@ export function createShaderHooksFunctions(strandsContext, fn, shader) {
595617 const propName = expectedProp . name ;
596618 const receivedValue = retNode [ propName ] ;
597619 if ( receivedValue === undefined ) {
598- FES . userError ( 'type error' , `You've returned an incomplete struct from ${ hookType . name } .\n` +
599- `Expected: { ${ expectedReturnType . properties . map ( p => p . name ) . join ( ', ' ) } }\n` +
600- `Received: { ${ Object . keys ( retNode ) . join ( ', ' ) } }\n` +
601- `All of the properties are required!` ) ;
620+ const expectedProps = expectedReturnType . properties . map ( p => p . name ) . join ( ', ' ) ;
621+ const receivedProps = Object . keys ( retNode ) . join ( ', ' ) ;
622+ FES . userError ( 'type error' ,
623+ `You've returned an incomplete ${ expectedStructType . typeName } struct from ${ hookType . name } .\n\n` +
624+ `Expected properties: { ${ expectedProps } }\n` +
625+ `Received properties: { ${ receivedProps } }\n\n` +
626+ `All properties are required! Make sure to include all properties in the returned struct.`
627+ ) ;
602628 }
603629 const expectedTypeInfo = expectedProp . dataType ;
604630 const returnedPropID = enforceReturnTypeMatch ( strandsContext , expectedTypeInfo , receivedValue , hookType . name ) ;
0 commit comments