public static void Rethrow(object context, int opCode) { AspNetCoreMvc2Integration integration = null; const string methodName = nameof(Rethrow); try { if (context.TryGetPropertyValue("HttpContext", out object httpContext)) { if (httpContext.TryGetPropertyValue("Items", out IDictionary <object, object> contextItems)) { integration = contextItems?[HttpContextKey] as AspNetCoreMvc2Integration; } } } catch (Exception ex) { Log.ErrorExceptionForFilter($"Error accessing {nameof(AspNetCoreMvc2Integration)}.", ex); } Action <object> rethrow; try { rethrow = RethrowAccess.GetInterceptedMethod( assembly: Assembly.GetCallingAssembly(), owningType: ResourceInvoker, returnType: Interception.VoidType, methodName: methodName, generics: Interception.NullTypeArray, parameters: Interception.ParamsToTypes(context)); } catch (Exception ex) { // profiled app will not continue working as expected without this rethrow method Log.ErrorException($"Error calling {ResourceInvoker}.{methodName}(object context)", ex); throw; } try { // call the original method, catching and rethrowing any unhandled exceptions rethrow.Invoke(context); } catch (Exception ex) when(integration?.SetException(ex) ?? false) { // unreachable code throw; } }
internal object InvokeGenericTaskDelegate( Type owningType, Type taskResultType, string nameOfIntegrationMethod, Type integrationType, params object[] parametersToPass) { var methodKey = Interception.MethodKey(owningType: owningType, returnType: taskResultType, genericTypes: Interception.NullTypeArray, parameterTypes: Interception.ParamsToTypes(parametersToPass)); var asyncDelegate = _methodCache.GetOrAdd(methodKey, _ => GetGenericAsyncMethodInfo(taskResultType, nameOfIntegrationMethod, integrationType)); return(asyncDelegate.Invoke(null, parametersToPass)); }
private static async Task ExecuteAsyncInternalNonGeneric(object wireProtocol, object connection, CancellationToken cancellationToken) { if (wireProtocol == null) { throw new ArgumentNullException(nameof(wireProtocol)); } const string methodName = nameof(ExecuteAsync); Func <object, object, CancellationToken, object> executeAsync = null; var wireProtocolType = wireProtocol.GetType(); try { executeAsync = ExecuteAsyncAccess.GetInterceptedMethod( owningType: wireProtocolType, returnType: typeof(Task), methodName: methodName, generics: Interception.NullTypeArray, parameters: Interception.ParamsToTypes(connection, cancellationToken)); } catch (Exception ex) { // profiled app will not continue working as expected without this method Log.ErrorException($"Error calling {wireProtocolType.Name}.{methodName}(IConnection connection, CancellationToken cancellationToken)", ex); } using (var scope = CreateScope(wireProtocol, connection)) { try { if (executeAsync == null) { throw new Exception(); } var taskObject = executeAsync(wireProtocol, connection, cancellationToken); var task = (Task)taskObject; await task.ConfigureAwait(false); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
public static object Execute(object wireProtocol, object connection, object cancellationTokenSource, int opCode) { if (wireProtocol == null) { throw new ArgumentNullException(nameof(wireProtocol)); } const string methodName = nameof(Execute); Func <object, object, CancellationToken, object> execute; var wireProtocolType = wireProtocol.GetType(); var tokenSource = cancellationTokenSource as CancellationTokenSource; var cancellationToken = tokenSource?.Token ?? CancellationToken.None; try { execute = ExecuteAccess.GetInterceptedMethod( wireProtocolType, returnType: null, // return type doesn't matter methodName: methodName, generics: Interception.NullTypeArray, parameters: Interception.ParamsToTypes(connection, cancellationToken)); } catch (Exception ex) { // profiled app will not continue working as expected without this method Log.ErrorException($"Error calling {wireProtocolType.Name}.{methodName}(IConnection connection, CancellationToken cancellationToken)", ex); throw; } using (var scope = CreateScope(wireProtocol, connection)) { try { return(execute(wireProtocol, connection, cancellationToken)); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
/// <summary> /// Attempts to retrieve a method from cache, otherwise creates the delegate reference, adds it to the cache, and then returns it. /// </summary> /// <param name="owningType">Type which owns the method.</param> /// <param name="methodName">Name of the method being instrumented.</param> /// <param name="returnType">The return type of the instrumented method.</param> /// <param name="generics">The ordered types of the method's generics.</param> /// <param name="parameters">The ordered types of the method's parameters.</param> /// <returns>Delegate representing instrumented method.</returns> internal TDelegate GetInterceptedMethod( Type owningType, string methodName, Type returnType, Type[] generics, Type[] parameters) { var methodKey = Interception.MethodKey(owningType: owningType, returnType: returnType, genericTypes: generics, parameterTypes: parameters); return (_methodCache.GetOrAdd( methodKey, key => Emit.DynamicMethodBuilder <TDelegate> .CreateInstrumentedMethodDelegate( owningType: owningType, methodName: methodName, returnType: returnType, parameterTypes: parameters, genericTypes: generics))); }