@@ -405,7 +405,12 @@ function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName
405405 }
406406 if ( receivedType . dimension !== expectedType . dimension ) {
407407 if ( receivedType . dimension !== 1 ) {
408- FES . userError ( 'type error' , `You have returned a vector with ${ receivedType . dimension } components in ${ hookName } when a ${ expectedType . baseType + expectedType . dimension } was expected!` ) ;
408+ const receivedTypeDisplay = receivedType . baseType + ( receivedType . dimension > 1 ? receivedType . dimension : '' ) ;
409+ const expectedTypeDisplay = expectedType . baseType + expectedType . dimension ;
410+ FES . userError ( 'type error' ,
411+ `You have returned a ${ receivedTypeDisplay } in ${ hookName } when a ${ expectedTypeDisplay } was expected!\n\n` +
412+ `Make sure your hook returns the correct type.`
413+ ) ;
409414 }
410415 else {
411416 const result = build . primitiveConstructorNode ( strandsContext , expectedType , returned ) ;
@@ -494,7 +499,24 @@ export function createShaderHooksFunctions(strandsContext, fn, shader) {
494499 if ( retNode instanceof StrandsNode ) {
495500 const returnedNode = getNodeDataFromID ( strandsContext . dag , retNode . id ) ;
496501 if ( returnedNode . baseType !== expectedStructType . typeName ) {
497- FES . userError ( "type error" , `You have returned a ${ retNode . baseType } from ${ hookType . name } when a ${ expectedStructType . typeName } was expected.` ) ;
502+ const receivedTypeName = returnedNode . baseType || 'undefined' ;
503+ const receivedDim = dag . dimensions [ retNode . id ] ;
504+ const receivedTypeDisplay = receivedDim > 1 ?
505+ `${ receivedTypeName } ${ receivedDim } ` : receivedTypeName ;
506+
507+ const expectedProps = expectedStructType . properties
508+ . map ( p => p . name ) . join ( ', ' ) ;
509+ FES . userError ( 'type error' ,
510+ `You have returned a ${ receivedTypeDisplay } from ${ hookType . name } when a ${ expectedStructType . typeName } was expected.\n\n` +
511+ `The ${ expectedStructType . typeName } struct has these properties: { ${ expectedProps } }\n\n` +
512+ `Instead of returning a different type, you should modify and return the ${ expectedStructType . typeName } struct that was passed to your hook.\n\n` +
513+ `For example:\n` +
514+ `${ hookType . name } ((inputs) => {\n` +
515+ ` // Modify properties of inputs\n` +
516+ ` inputs.someProperty = ...;\n` +
517+ ` return inputs; // Return the modified struct\n` +
518+ `})`
519+ ) ;
498520 }
499521 const newDeps = returnedNode . dependsOn . slice ( ) ;
500522 for ( let i = 0 ; i < expectedStructType . properties . length ; i ++ ) {
@@ -513,10 +535,14 @@ export function createShaderHooksFunctions(strandsContext, fn, shader) {
513535 const propName = expectedProp . name ;
514536 const receivedValue = retNode [ propName ] ;
515537 if ( receivedValue === undefined ) {
516- FES . userError ( 'type error' , `You've returned an incomplete struct from ${ hookType . name } .\n` +
517- `Expected: { ${ expectedReturnType . properties . map ( p => p . name ) . join ( ', ' ) } }\n` +
518- `Received: { ${ Object . keys ( retNode ) . join ( ', ' ) } }\n` +
519- `All of the properties are required!` ) ;
538+ const expectedProps = expectedReturnType . properties . map ( p => p . name ) . join ( ', ' ) ;
539+ const receivedProps = Object . keys ( retNode ) . join ( ', ' ) ;
540+ FES . userError ( 'type error' ,
541+ `You've returned an incomplete ${ expectedStructType . typeName } struct from ${ hookType . name } .\n\n` +
542+ `Expected properties: { ${ expectedProps } }\n` +
543+ `Received properties: { ${ receivedProps } }\n\n` +
544+ `All properties are required! Make sure to include all properties in the returned struct.`
545+ ) ;
520546 }
521547 const expectedTypeInfo = expectedProp . dataType ;
522548 const returnedPropID = enforceReturnTypeMatch ( strandsContext , expectedTypeInfo , receivedValue , hookType . name ) ;
0 commit comments