@@ -409,6 +409,61 @@ public async Task RestorePackagesAsync_WithUpdatedReferences_TriggersShutdown(bo
409409 }
410410 }
411411
412+ [ Fact ]
413+ public async Task GetFunctionTargetAsync_CompilationError_ReportsResultsToScriptHostFunctionErrors ( )
414+ {
415+ // Create the compilation exception we expect to throw
416+ var descriptor = new DiagnosticDescriptor ( DotNetConstants . MissingFunctionEntryPointCompilationCode ,
417+ "Test compilation exception" , "Test compilation error" , "AzureFunctions" , DiagnosticSeverity . Error , true ) ;
418+ var exception = new CompilationErrorException ( "Test compilation exception" , ImmutableArray . Create ( Diagnostic . Create ( descriptor , Location . None ) ) ) ;
419+
420+ // Create the invoker dependencies and setup the appropriate method to throw the exception
421+ RunDependencies dependencies = CreateDependencies ( ) ;
422+ dependencies . Compilation . Setup ( c => c . GetEntryPointSignature ( It . IsAny < IFunctionEntryPointResolver > ( ) , It . IsAny < Assembly > ( ) ) )
423+ . Throws ( exception ) ;
424+ dependencies . Compilation . Setup ( c => c . EmitAsync ( It . IsAny < CancellationToken > ( ) ) )
425+ . ReturnsAsync ( DotNetCompilationResult . FromPath ( typeof ( DotNetFunctionInvokerTests ) . Assembly . Location ) ) ;
426+
427+ string functionName = Guid . NewGuid ( ) . ToString ( ) ;
428+ string rootFunctionsFolder = Path . Combine ( Path . GetTempPath ( ) , functionName ) ;
429+ Directory . CreateDirectory ( rootFunctionsFolder ) ;
430+
431+ // Create a dummy file to represent our function
432+ string filePath = Path . Combine ( rootFunctionsFolder , Guid . NewGuid ( ) . ToString ( ) + ".csx" ) ;
433+ File . WriteAllText ( filePath , string . Empty ) ;
434+
435+ var metadata = new FunctionMetadata
436+ {
437+ ScriptFile = filePath ,
438+ FunctionDirectory = Path . GetDirectoryName ( filePath ) ,
439+ Name = functionName ,
440+ Language = DotNetScriptTypes . CSharp
441+ } ;
442+
443+ metadata . Bindings . Add ( new BindingMetadata ( ) { Name = "Test" , Type = "ManualTrigger" } ) ;
444+
445+ var invoker = new DotNetFunctionInvoker ( dependencies . Host , metadata , new Collection < FunctionBinding > ( ) , new Collection < FunctionBinding > ( ) ,
446+ dependencies . EntrypointResolver . Object , dependencies . CompilationServiceFactory . Object , dependencies . LoggerFactory , dependencies . MetricsLogger ,
447+ new Collection < IScriptBindingProvider > ( ) ) ;
448+
449+ // Send file change notification to trigger a reload
450+ var fileEventArgs = new FileSystemEventArgs ( WatcherChangeTypes . Changed , Path . GetTempPath ( ) , Path . Combine ( Path . GetFileName ( rootFunctionsFolder ) , Path . GetFileName ( filePath ) ) ) ;
451+ dependencies . Host . EventManager . Publish ( new FileEvent ( EventSources . ScriptFiles , fileEventArgs ) ) ;
452+
453+ await Assert . ThrowsAsync < CompilationErrorException > ( async ( ) =>
454+ {
455+ await invoker . GetFunctionTargetAsync ( ) ;
456+ } ) ;
457+
458+ dependencies . Host . FunctionErrors . TryGetValue ( functionName , out ICollection < string > functionErrors ) ;
459+ Console . WriteLine ( functionErrors ) ;
460+ Assert . True ( functionErrors . Any ( ) ) ;
461+ foreach ( string error in functionErrors )
462+ {
463+ Assert . StartsWith ( "Microsoft.CodeAnalysis.Scripting.CompilationErrorException: Test compilation exception" , error ) ;
464+ }
465+ }
466+
412467 // TODO: DI (FACAVAL) Use test helpers to create host and inject services
413468 private RunDependencies CreateDependencies ( Action < IServiceCollection > configureServices = null )
414469 {
0 commit comments