@@ -539,50 +539,56 @@ impl ProtoNetwork {
539539#[ derive( Clone , PartialEq , serde:: Serialize , serde:: Deserialize ) ]
540540pub enum GraphErrorType {
541541 NodeNotFound ( NodeId ) ,
542- UnexpectedGenerics { index : usize , inputs : Vec < Type > } ,
542+ UnexpectedGenerics {
543+ index : usize ,
544+ inputs : Vec < Type > ,
545+ } ,
543546 NoImplementations ,
544547 NoConstructor ,
545- InvalidImplementations { inputs : String , error_inputs : Vec < Vec < ( usize , ( Type , Type ) ) > > } ,
546- MultipleImplementations { inputs : String , valid : Vec < NodeIOTypes > } ,
548+ // The first vec represents a list of correct NodeIOTypes
549+ // The second vec represents what the input index and what it expects
550+ InvalidImplementations {
551+ identifier : ProtoNodeIdentifier ,
552+ inputs : String ,
553+ error_inputs : Vec < Vec < ( usize , Type ) > > ,
554+ } ,
555+ MultipleImplementations {
556+ inputs : String ,
557+ valid : Vec < NodeIOTypes > ,
558+ } ,
547559}
548560impl Debug for GraphErrorType {
549- // TODO: format with the document graph context so the input index is the same as in the graph UI.
550561 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
551562 match self {
552563 GraphErrorType :: NodeNotFound ( id) => write ! ( f, "Input node {id} is not present in the typing context" ) ,
553564 GraphErrorType :: UnexpectedGenerics { index, inputs } => write ! ( f, "Generic inputs should not exist but found at {index}: {inputs:?}" ) ,
554565 GraphErrorType :: NoImplementations => write ! ( f, "No implementations found" ) ,
555566 GraphErrorType :: NoConstructor => write ! ( f, "No construct found for node" ) ,
556- GraphErrorType :: InvalidImplementations { inputs, error_inputs } => {
557- let format_error = |( index, ( found, expected) ) : & ( usize , ( Type , Type ) ) | {
558- let index = index + 1 ;
559- format ! (
560- "\
561- • Input {index}:\n \
562- …found: {found}\n \
563- …expected: {expected}\
564- "
565- )
566- } ;
567- let format_error_list = |errors : & Vec < ( usize , ( Type , Type ) ) > | errors. iter ( ) . map ( format_error) . collect :: < Vec < _ > > ( ) . join ( "\n " ) ;
568- let mut errors = error_inputs. iter ( ) . map ( format_error_list) . collect :: < Vec < _ > > ( ) ;
569- errors. sort ( ) ;
570- let errors = errors. join ( "\n " ) ;
571- let incompatibility = if errors. chars ( ) . filter ( |& c| c == '•' ) . count ( ) == 1 {
572- "This input type is incompatible:"
573- } else {
574- "These input types are incompatible:"
575- } ;
576-
567+ GraphErrorType :: InvalidImplementations { identifier, inputs, error_inputs } => {
568+ let plural = if error_inputs. first ( ) . is_some_and ( |first| first. len ( ) > 1 ) { "s" } else { "" } . to_string ( ) ;
569+ let solutions = error_inputs
570+ . iter ( )
571+ . map ( |expected_inputs| {
572+ expected_inputs
573+ . iter ( )
574+ . enumerate ( )
575+ . map ( |( error_index, ( input_index, expected_type) ) | {
576+ let pre_text = if error_index == 0 { "• " } else { " " } ;
577+ format ! ( "{}Input {} expected: {}\n " , pre_text, input_index + 1 , expected_type)
578+ } )
579+ . collect :: < String > ( )
580+ } )
581+ . collect :: < Vec < _ > > ( )
582+ . join ( "\n " ) ;
583+ let node_name = identifier. name . to_string ( ) ;
577584 write ! (
578585 f,
579- "\
580- {incompatibility}\n \
581- {errors}\n \
582- \n \
583- The node is currently receiving all of the following input types:\n \
584- {inputs}\n \
585- This is not a supported arrangement of types for the node.\
586+ "Potential solutions for invalid input{plural}:\n \
587+ {solutions}\n \
588+ The node is currently receiving the following input types:\n \
589+ {inputs}\n \n \
590+ This is not a supported arrangement of types for:\n \
591+ {node_name}\
586592 "
587593 )
588594 }
@@ -766,10 +772,7 @@ impl TypingContext {
766772 . zip ( [ & node_io. call_argument ] . into_iter ( ) . chain ( & node_io. inputs ) . cloned ( ) )
767773 . enumerate ( )
768774 . filter ( |( _, ( p1, p2) ) | !valid_type ( p1, p2) )
769- . map ( |( index, ty) | {
770- let i = node. original_location . inputs ( index) . min_by_key ( |s| s. node . len ( ) ) . map ( |s| s. index ) . unwrap_or ( index) ;
771- ( i, ty)
772- } )
775+ . map ( |( index, ( _, expected) ) | ( index - 1 , expected) )
773776 . collect :: < Vec < _ > > ( ) ;
774777 if current_errors. len ( ) < best_errors {
775778 best_errors = current_errors. len ( ) ;
@@ -779,14 +782,16 @@ impl TypingContext {
779782 error_inputs. push ( current_errors) ;
780783 }
781784 }
782- let inputs = [ call_argument]
783- . into_iter ( )
784- . chain ( & inputs)
785- . enumerate ( )
786- . filter_map ( |( i, t) | if i == 0 { None } else { Some ( format ! ( "• Input {i}: {t}" ) ) } )
787- . collect :: < Vec < _ > > ( )
788- . join ( "\n " ) ;
789- Err ( vec ! [ GraphError :: new( node, GraphErrorType :: InvalidImplementations { inputs, error_inputs } ) ] )
785+
786+ let inputs = inputs. into_iter ( ) . enumerate ( ) . map ( |( i, t) | format ! ( "• Input {}: {}" , i + 1 , t) ) . collect :: < Vec < _ > > ( ) . join ( "\n " ) ;
787+ Err ( vec ! [ GraphError :: new(
788+ node,
789+ GraphErrorType :: InvalidImplementations {
790+ identifier: node. identifier. clone( ) ,
791+ inputs,
792+ error_inputs,
793+ } ,
794+ ) ] )
790795 }
791796 [ ( node_io, org_nio) ] => {
792797 let node_io = node_io. clone ( ) ;
0 commit comments