public static FlattenException ( |
||
ex | ||
sourceFormatter | string>.Func | |
includeSource | bool | |
return | string |
internal Collection <FunctionDescriptor> ReadFunctions(List <FunctionMetadata> functions, IEnumerable <FunctionDescriptorProvider> descriptorProviders) { Collection <FunctionDescriptor> functionDescriptors = new Collection <FunctionDescriptor>(); foreach (FunctionMetadata metadata in functions) { try { FunctionDescriptor descriptor = null; foreach (var provider in descriptorProviders) { if (provider.TryCreate(metadata, out descriptor)) { break; } } if (descriptor != null) { functionDescriptors.Add(descriptor); } } catch (Exception ex) { // log any unhandled exceptions and continue AddFunctionError(metadata.Name, Utility.FlattenException(ex, includeSource: false)); } } return(functionDescriptors); }
private FunctionMetadata ReadFunctionMetadata(string functionDirectory, IFileSystem fileSystem, IEnumerable <RpcWorkerConfig> workerConfigs) { using (_metricsLogger.LatencyEvent(string.Format(MetricEventNames.ReadFunctionMetadata, functionDirectory))) { string functionName = null; try { // read the function config if (!Utility.TryReadFunctionConfig(functionDirectory, out string json, fileSystem)) { // not a function directory return(null); } functionName = Path.GetFileName(functionDirectory); ValidateName(functionName); JObject functionConfig = JObject.Parse(json); return(ParseFunctionMetadata(functionName, functionConfig, functionDirectory, fileSystem, workerConfigs)); } catch (Exception ex) { // log any unhandled exceptions and continue Utility.AddFunctionError(_functionErrors, functionName, Utility.FlattenException(ex, includeSource: false), isFunctionShortName: true); } return(null); } }
private void HandleHostError(Microsoft.Azure.WebJobs.Extensions.TraceFilter traceFilter) { foreach (TraceEvent traceEvent in traceFilter.Events) { if (traceEvent.Exception is FunctionInvocationException) { // For all function invocation events, we notify the invoker so it can // log the error as needed to its function specific logs. FunctionInvocationException invocationException = traceEvent.Exception as FunctionInvocationException; NotifyInvoker(invocationException.MethodName, invocationException); } else if (traceEvent.Exception is FunctionIndexingException) { // For all startup time indexing errors, we accumulate them per function FunctionIndexingException indexingException = traceEvent.Exception as FunctionIndexingException; string formattedError = Utility.FlattenException(indexingException); AddFunctionError(indexingException.MethodName, formattedError); // Also notify the invoker so the error can also be written to the function // log file NotifyInvoker(indexingException.MethodName, indexingException); // Mark the error as handled so indexing will continue indexingException.Handled = true; } } }
private Collection <FunctionDescriptor> ReadFunctions(IEnumerable <FunctionDescriptorProvider> descriptorProviders) { var functions = new List <FunctionMetadata>(); foreach (var scriptDir in Directory.EnumerateDirectories(ScriptConfig.RootScriptPath)) { string functionName = null; try { // read the function config string functionConfigPath = Path.Combine(scriptDir, ScriptConstants.FunctionMetadataFileName); if (!File.Exists(functionConfigPath)) { // not a function directory continue; } functionName = Path.GetFileName(scriptDir); if (ScriptConfig.Functions != null && !ScriptConfig.Functions.Contains(functionName, StringComparer.OrdinalIgnoreCase)) { // a functions filter has been specified and the current function is // not in the filter list continue; } ValidateFunctionName(functionName); string json = File.ReadAllText(functionConfigPath); JObject functionConfig = JObject.Parse(json); Lazy <string[]> functionFiles = new Lazy <string[]>(() => Directory.EnumerateFiles(scriptDir).Where(p => Path.GetFileName(p).ToLowerInvariant() != ScriptConstants.FunctionMetadataFileName).ToArray()); string functionError = null; FunctionMetadata functionMetadata = null; var mappedHttpFunctions = new Dictionary <string, HttpTriggerBindingMetadata>(); if (!TryParseFunctionMetadata(functionName, functionConfig, mappedHttpFunctions, TraceWriter, functionFiles, out functionMetadata, out functionError)) { // for functions in error, log the error and don't // add to the functions collection AddFunctionError(functionName, functionError); continue; } else if (functionMetadata != null) { functions.Add(functionMetadata); } } catch (Exception ex) { // log any unhandled exceptions and continue AddFunctionError(functionName, Utility.FlattenException(ex, includeSource: false), isFunctionShortName: true); } } return(ReadFunctions(functions, descriptorProviders)); }
internal IEnumerable <FunctionMetadata> ValidateMetadata(IEnumerable <RawFunctionMetadata> functions) { List <FunctionMetadata> validatedMetadata = new List <FunctionMetadata>(); if (IsNullOrEmpty(functions)) { _logger.LogDebug("There is no metadata to be validated."); return(validatedMetadata); } _functionErrors.Clear(); foreach (RawFunctionMetadata rawFunction in functions) { var function = rawFunction.Metadata; try { Utility.ValidateName(function.Name); function.Language = SystemEnvironment.Instance.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeSettingName); // skip function directory validation because this involves reading function.json // skip function ScriptFile validation for now because this involves enumerating file directory // configuration source validation if (!string.IsNullOrEmpty(rawFunction.ConfigurationSource)) { JToken isDirect = JToken.Parse(rawFunction.ConfigurationSource); var isDirectValue = isDirect?.ToString(); if (string.Equals(isDirectValue, "attributes", StringComparison.OrdinalIgnoreCase)) { function.SetIsDirect(true); } else if (!string.Equals(isDirectValue, "config", StringComparison.OrdinalIgnoreCase)) { throw new FormatException($"Illegal value '{isDirectValue}' for 'configurationSource' property in {function.Name}'."); } } // retry option validation if (!string.IsNullOrEmpty(rawFunction.RetryOptions)) { function.Retry = JObject.Parse(rawFunction.RetryOptions).ToObject <RetryOptions>(); Utility.ValidateRetryOptions(function.Retry); } // binding validation function = ValidateBindings(rawFunction.Bindings, function); // add validated metadata to validated list if it gets this far validatedMetadata.Add(function); } catch (Exception ex) { Utility.AddFunctionError(_functionErrors, function.Name, Utility.FlattenException(ex, includeSource: false), isFunctionShortName: true); } } return(validatedMetadata); }
private static (Collection <FunctionMetadata>, ProxyClientExecutor) LoadProxyMetadata(string proxiesJson, Dictionary <string, ICollection <string> > functionErrors, ILogger logger) { var proxies = new Collection <FunctionMetadata>(); ProxyClientExecutor client = null; var rawProxyClient = ProxyClientFactory.Create(proxiesJson, logger); if (rawProxyClient != null) { client = new ProxyClientExecutor(rawProxyClient); } if (client == null) { return(proxies, null); } var routes = client.GetProxyData(); foreach (var route in routes.Routes) { try { // Proxy names should follow the same naming restrictions as in function names. If not, invalid characters will be removed. var proxyName = NormalizeProxyName(route.Name); var proxyMetadata = new FunctionMetadata(); var json = new JObject { { "authLevel", "anonymous" }, { "name", "req" }, { "type", "httptrigger" }, { "direction", "in" }, { "Route", route.UrlTemplate.TrimStart('/') }, { "Methods", new JArray(route.Methods.Select(m => m.Method.ToString()).ToArray()) } }; BindingMetadata bindingMetadata = BindingMetadata.Create(json); proxyMetadata.Bindings.Add(bindingMetadata); proxyMetadata.Name = proxyName; proxyMetadata.IsProxy = true; proxies.Add(proxyMetadata); } catch (Exception ex) { // log any unhandled exceptions and continue Utility.AddFunctionError(functionErrors, route.Name, Utility.FlattenException(ex, includeSource: false), isFunctionShortName: true); } } return(proxies, client); }
internal async Task <Collection <FunctionDescriptor> > GetFunctionDescriptorsAsync(IEnumerable <FunctionMetadata> functions, IEnumerable <FunctionDescriptorProvider> descriptorProviders, CancellationToken cancellationToken) { Collection <FunctionDescriptor> functionDescriptors = new Collection <FunctionDescriptor>(); if (!cancellationToken.IsCancellationRequested) { var httpFunctions = new Dictionary <string, HttpTriggerAttribute>(); Utility.VerifyFunctionsMatchSpecifiedLanguage(functions, _workerRuntime, _environment.IsPlaceholderModeEnabled(), _isHttpWorker, cancellationToken); foreach (FunctionMetadata metadata in functions) { try { bool created = false; FunctionDescriptor descriptor = null; foreach (var provider in descriptorProviders) { (created, descriptor) = await provider.TryCreate(metadata); if (created) { break; } } if (descriptor != null) { ValidateFunction(descriptor, httpFunctions); functionDescriptors.Add(descriptor); } // If this is metadata represents a function that supports direct type indexing, // set that type int he function metadata TrySetDirectType(metadata); } catch (Exception ex) { // log any unhandled exceptions and continue Utility.AddFunctionError(FunctionErrors, metadata.Name, Utility.FlattenException(ex, includeSource: false)); } } VerifyPrecompileStatus(functionDescriptors); } return(functionDescriptors); }
private void HandleHostError(Exception exception) { if (exception == null) { throw new ArgumentNullException("exception"); } // First, ensure that we've logged to the host log // Also ensure we flush immediately to ensure any buffered logs // are written TraceWriter.Error("A ScriptHost error has occurred", exception); TraceWriter.Flush(); if (exception is FunctionInvocationException) { // For all function invocation errors, we notify the invoker so it can // log the error as needed to its function specific logs. FunctionInvocationException invocationException = exception as FunctionInvocationException; NotifyInvoker(invocationException.MethodName, invocationException); } else if (exception is FunctionIndexingException) { // For all startup time indexing errors, we accumulate them per function FunctionIndexingException indexingException = exception as FunctionIndexingException; string formattedError = Utility.FlattenException(indexingException); AddFunctionError(indexingException.MethodName, formattedError); // Also notify the invoker so the error can also be written to the function // log file NotifyInvoker(indexingException.MethodName, indexingException); // Mark the error as handled so indexing will continue indexingException.Handled = true; } else { // See if we can identify which function caused the error, and if we can // log the error as needed to its function specific logs. FunctionDescriptor function = null; if (TryGetFunctionFromException(Functions, exception, out function)) { NotifyInvoker(function.Name, exception); } } }
internal async Task <Collection <FunctionDescriptor> > GetFunctionDescriptorsAsync(IEnumerable <FunctionMetadata> functions, IEnumerable <FunctionDescriptorProvider> descriptorProviders) { Collection <FunctionDescriptor> functionDescriptors = new Collection <FunctionDescriptor>(); var httpFunctions = new Dictionary <string, HttpTriggerAttribute>(); if (!_environment.IsPlaceholderModeEnabled()) { Utility.VerifyFunctionsMatchSpecifiedLanguage(functions, _workerRuntime); } foreach (FunctionMetadata metadata in functions) { try { bool created = false; FunctionDescriptor descriptor = null; foreach (var provider in descriptorProviders) { (created, descriptor) = await provider.TryCreate(metadata); if (created) { break; } } if (descriptor != null) { ValidateFunction(descriptor, httpFunctions); functionDescriptors.Add(descriptor); } } catch (Exception ex) { // log any unhandled exceptions and continue Utility.AddFunctionError(FunctionErrors, metadata.Name, Utility.FlattenException(ex, includeSource: false)); } } VerifyPrecompileStatus(functionDescriptors); return(functionDescriptors); }
internal async Task <Collection <FunctionDescriptor> > GetFunctionDescriptorsAsync(IEnumerable <FunctionMetadata> functions, IEnumerable <FunctionDescriptorProvider> descriptorProviders) { Collection <FunctionDescriptor> functionDescriptors = new Collection <FunctionDescriptor>(); var httpFunctions = new Dictionary <string, HttpTriggerAttribute>(); if (!_scriptHostEnvironment.IsDevelopment() && !Utility.IsSingleLanguage(functions, _currentRuntimelanguage)) { throw new HostInitializationException($"Found functions with more than one language. Select a language for your function app by specifying {LanguageWorkerConstants.FunctionWorkerRuntimeSettingName} AppSetting"); } foreach (FunctionMetadata metadata in functions) { try { bool created = false; FunctionDescriptor descriptor = null; foreach (var provider in descriptorProviders) { (created, descriptor) = await provider.TryCreate(metadata); if (created) { break; } } if (descriptor != null) { ValidateFunction(descriptor, httpFunctions); functionDescriptors.Add(descriptor); } } catch (Exception ex) { // log any unhandled exceptions and continue Utility.AddFunctionError(FunctionErrors, metadata.Name, Utility.FlattenException(ex, includeSource: false)); } } VerifyPrecompileStatus(functionDescriptors); return(functionDescriptors); }
private void HandleHostError(Exception exception) { if (exception == null) { throw new ArgumentNullException("exception"); } // Note: We do not log to ILogger here as any error has already been logged. if (exception is FunctionInvocationException) { // For all function invocation errors, we notify the invoker so it can // log the error as needed to its function specific logs. FunctionInvocationException invocationException = exception as FunctionInvocationException; NotifyInvoker(invocationException.MethodName, invocationException); } else if (exception is FunctionIndexingException || exception is FunctionListenerException) { // For all startup time indexing/listener errors, we accumulate them per function FunctionException functionException = exception as FunctionException; string formattedError = Utility.FlattenException(functionException); Utility.AddFunctionError(FunctionErrors, functionException.MethodName, formattedError); // Also notify the invoker so the error can also be written to the function // log file NotifyInvoker(functionException.MethodName, functionException); } else if (exception is LanguageWorkerChannelException) { AddLanguageWorkerChannelErrors(_functionDispatcher, FunctionErrors); } else { // See if we can identify which function caused the error, and if we can // log the error as needed to its function specific logs. if (TryGetFunctionFromException(Functions, exception, out FunctionDescriptor function)) { NotifyInvoker(function.Name, exception); } } }
internal Collection <FunctionDescriptor> GetFunctionDescriptors(IEnumerable <FunctionMetadata> functions, IEnumerable <FunctionDescriptorProvider> descriptorProviders) { Collection <FunctionDescriptor> functionDescriptors = new Collection <FunctionDescriptor>(); var httpFunctions = new Dictionary <string, HttpTriggerAttribute>(); if (!Utility.IsSingleLanguage(functions, _language)) { _logger.LogError($"Found functions with more than one language. Select a language for your function app by specifying {LanguageWorkerConstants.FunctionWorkerRuntimeSettingName} AppSetting"); return(functionDescriptors); } foreach (FunctionMetadata metadata in functions) { try { FunctionDescriptor descriptor = null; foreach (var provider in descriptorProviders) { if (provider.TryCreate(metadata, out descriptor)) { break; } } if (descriptor != null) { ValidateFunction(descriptor, httpFunctions); functionDescriptors.Add(descriptor); } } catch (Exception ex) { // log any unhandled exceptions and continue Utility.AddFunctionError(FunctionErrors, metadata.Name, Utility.FlattenException(ex, includeSource: false)); } } VerifyPrecompileStatus(functionDescriptors); return(functionDescriptors); }
private void ProcessLeaseTimerTick(object state) { if (_processingLease) { return; } _processingLease = true; AcquireOrRenewLeaseAsync() .ContinueWith(t => { if (t.IsFaulted) { t.Exception.Handle(e => { ProcessLeaseError(Utility.FlattenException(e)); return(true); }); } _processingLease = false; }, TaskContinuationOptions.ExecuteSynchronously); }
internal static void AddLanguageWorkerChannelErrors(IFunctionDispatcher functionDispatcher, IDictionary <string, ICollection <string> > functionErrors) { foreach (KeyValuePair <WorkerConfig, LanguageWorkerState> kvp in functionDispatcher.LanguageWorkerChannelStates) { WorkerConfig workerConfig = kvp.Key; LanguageWorkerState workerState = kvp.Value; foreach (var functionRegistrationContext in workerState.GetRegistrations()) { var exMessage = $"Failed to start language worker process for: {workerConfig.Language}"; var languageWorkerChannelException = workerState.Errors != null && workerState.Errors.Count > 0 ? new LanguageWorkerChannelException(exMessage, workerState.Errors[workerState.Errors.Count - 1]) : new LanguageWorkerChannelException(exMessage); Utility.AddFunctionError(functionErrors, functionRegistrationContext.Metadata.Name, Utility.FlattenException(languageWorkerChannelException, includeSource: false)); } } }