public void Handle(Agent agent, Action <object> responseWriter) { object result = null; Task.Factory.StartNew( async() => { try { result = await HandleAsync(agent); if (result == null && !CanReturnNull) { throw new Exception($"{GetType ()}.Handle(Agent) returned null"); } } catch (Exception e) { result = new XipErrorMessage { Message = $"{GetType ()}.Handle(Agent) threw an exception", Exception = ExceptionNode.Create(e) }; } }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, MainThread.TaskScheduler).Unwrap().Wait(); responseWriter(result); }
public GetMemberValueError(Exception exception = null) { if (exception != null) { Exception = ExceptionNode.Create(exception); } }
/// <summary>Развертывание информации в ExceptionNode из полученного экземпляра обьекта</summary> public static ExceptionNode DispatchNode(object obj) { ExceptionNode node = new ExceptionNode(); //TODO: дописать разбор объекта node.Value = obj.ToString(); return node; }
public ExceptionNode( TypeSpec type, string message, StackTrace stackTrace, ExceptionNode innerException) { Type = type; Message = message; StackTrace = stackTrace; InnerException = innerException; }
public static ExceptionNode Create(Exception exception) { if (exception == null) { return(null); } return(new ExceptionNode( TypeSpec.Create(exception.GetType()), exception.Message, StackTrace.Create(new System.Diagnostics.StackTrace(exception, true)), ExceptionNode.Create(exception.InnerException))); }
protected override void HandleBind() { var xipException = RenderState.Source as XipErrorMessageException; if (xipException != null) { message = xipException.XipErrorMessage.Message; exception = xipException.XipErrorMessage.Exception; } else { var e = (Exception)RenderState.Source; message = e.Message; exception = ExceptionNode.Create(e); } }
/// <summary> /// Dicards the captured traces and frames that are a result of compiler-generated /// code to host the submission so we only render frames the user might actually expect. /// </summary> static ExceptionNode FilterException(ExceptionNode exception) { try { var capturedTraces = exception?.StackTrace?.CapturedTraces; if (capturedTraces == null || capturedTraces.Count != 2) { return(exception); } var submissionTrace = capturedTraces [0]; exception.StackTrace = exception.StackTrace.WithCapturedTraces(new [] { submissionTrace.WithFrames( submissionTrace.Frames.Take(submissionTrace.Frames.Count - 1)) }); return(exception); } catch (Exception e) { Log.Error(TAG, $"error filtering ExceptionNode [[{exception}]]", e); return(exception); } }
public override void VisitExceptionNode(ExceptionNode exception) { if (exceptionDepth == 0) { Writer.Write("<div class=\"exception root\">"); } else { Writer.Write("<div class=\"exception inner\">"); } Writer.Write("<h1 onclick=\"exceptionToggle(this)\">"); VisitTypeSpec(exception.Type); if (!String.IsNullOrEmpty(exception.Message)) { Writer.Write(": "); Writer.WriteSpan("message", exception.Message); } Writer.Write("</h1>"); Writer.Write("<div class=\"contents\">"); exception.StackTrace.AcceptVisitor(this); if (exception.InnerException != null) { exceptionDepth++; exception.InnerException.AcceptVisitor(this); exceptionDepth--; } Writer.Write("</div>"); Writer.Write("</div>"); }
/// <summary> /// Called on every representation to perform a normalization pass /// to convert many common object types to those that can be serialized /// in a normalized way. This provides a small safety layer as well, /// ensuring that we are only serializing objects that are safe/supported /// to do so across all agents*clients or explicitly declare themselves /// as an IRepresentationObject (an opt-in "contract" that says that /// clients should be able to deserialize it). /// </summary> /// <param name="obj">The object to normalize.</param> object Normalize(object obj) { if (obj == null) { return(null); } if (obj is Representation) { // an object may be boxed in a Representation object if it has metadata // associated with it, such as whether the representation provider supports // "editing" via TryConvertFromRepresentation. We must still normalize the // value inside to ensure we can safely serialize it. If the value differs // after normalization, but is serializable, we re-box it with the normalized // value and the canEdit flag unset. var originalRepresentation = (Representation)obj; var normalizedRepresentationValue = Normalize(originalRepresentation.Value); if (Equals(originalRepresentation.Value, normalizedRepresentationValue)) { return(obj); } if (normalizedRepresentationValue == null) { return(null); } return(originalRepresentation.With( normalizedRepresentationValue, canEdit: false)); } if (agentRepresentationProvider != null) { try { var normalized = agentRepresentationProvider.NormalizeRepresentation(obj); if (normalized != null) { return(normalized); } } catch (Exception e) { Log.Error(TAG, "Agent-builtin normalizer raised an exception", e); } } if (obj is Enum) { return(new EnumValue((Enum)obj)); } if (obj is IInteractiveObject) { var interactive = (IInteractiveObject)obj; interactive.Handle = ObjectCache.Shared.GetHandle(interactive); return(interactive); } if (obj is IRepresentationObject) { return(obj); } if (obj is ISerializableObject && currentPreparePassAllowsISerializableObject) { return((JsonPayload)((ISerializableObject)obj).SerializeToString()); } if (obj is IFallbackRepresentationObject) { return(obj); } if (obj is Exception) { return(ExceptionNode.Create((Exception)obj)); } if (obj is MemberInfo) { try { var remoteMemberInfo = TypeMember.Create((MemberInfo)obj); if (remoteMemberInfo != null) { return(remoteMemberInfo); } } catch { } } if (obj is TimeSpan || obj is Guid) { return(obj); } if (obj is IntPtr) { return(new WordSizedNumber( obj, WordSizedNumberFlags.Pointer | WordSizedNumberFlags.Signed, (ulong)(IntPtr)obj)); } if (obj is UIntPtr) { return(new WordSizedNumber( obj, WordSizedNumberFlags.Pointer, (ulong)(UIntPtr)obj)); } if (Type.GetTypeCode(obj.GetType()) != TypeCode.Object) { return(obj); } if (obj is byte []) { return(obj); } return(null); }
GetMemberValueError(ExceptionNode exception) => Exception = exception;
async Task <EvaluationStatus> CoreEvaluateCodeCellAsync( CodeCellState codeCellState, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken = ClientSession.CancellationToken.LinkWith(cancellationToken); if (!ClientSession.Agent.IsConnected || ClientSession.CompilationWorkspace == null) { codeCellState.View.IsEvaluating = false; codeCellState.View.HasErrorDiagnostics = true; codeCellState.View.RenderDiagnostic(new Diagnostic( DiagnosticSeverity.Error, "Cannot evaluate: not connected to agent.")); return(EvaluationStatus.Disconnected); } CodeAnalysis.Compilation compilation = null; IReadOnlyList <Diagnostic> diagnostics = null; ExceptionNode exception = null; bool agentTerminatedWhileEvaluating = false; try { compilation = await ClientSession.CompilationWorkspace.EmitCellCompilationAsync( codeCellState.CodeCellId, new EvaluationEnvironment (ClientSession.WorkingDirectory), cancellationToken); diagnostics = await ClientSession.CompilationWorkspace.GetCellDiagnosticsAsync( codeCellState.CodeCellId, cancellationToken); var integrationAssemblies = compilation .References .Where(ra => ra.HasIntegration) .ToArray(); if (integrationAssemblies.Length > 0) { await ClientSession.Agent.Api.EvaluationContextManager.LoadAssembliesAsync( TargetCompilationConfiguration.EvaluationContextId, integrationAssemblies); } } catch (Exception e) { exception = ExceptionNode.Create(e); } var hasErrorDiagnostics = codeCellState.View.HasErrorDiagnostics = diagnostics .Any(d => d.Severity == DiagnosticSeverity.Error); foreach (var diagnostic in diagnostics) { codeCellState.View.RenderDiagnostic(diagnostic); } try { if (compilation != null) { await ClientSession.Agent.Api.EvaluationContextManager.EvaluateAsync( TargetCompilationConfiguration.EvaluationContextId, compilation, cancellationToken); } } catch (XipErrorMessageException e) { exception = e.XipErrorMessage.Exception; } catch (Exception e) { Log.Error(TAG, "marking agent as terminated", e); agentTerminatedWhileEvaluating = true; codeCellState.View.HasErrorDiagnostics = true; codeCellState.View.RenderDiagnostic(new Diagnostic( DiagnosticSeverity.Error, Catalog.GetString( "The application terminated during evaluation of this cell. " + "Run this cell manually to try again."))); } codeCellState.View.IsEvaluating = false; EvaluationStatus evaluationStatus; if (exception != null) { codeCellState.View.RenderResult( CultureInfo.CurrentCulture, exception, EvaluationResultHandling.Replace); evaluationStatus = EvaluationStatus.EvaluationException; } else if (hasErrorDiagnostics) { return(EvaluationStatus.ErrorDiagnostic); } else if (agentTerminatedWhileEvaluating) { evaluationStatus = EvaluationStatus.Disconnected; } else { evaluationStatus = EvaluationStatus.Success; } if (ClientSession.SessionKind != ClientSessionKind.Workbook) { codeCellState.Freeze(); } codeCellState.NotifyEvaluated(agentTerminatedWhileEvaluating); return(evaluationStatus); }
public virtual void VisitExceptionNode(ExceptionNode exception);
public XipErrorMessage (string message, ExceptionNode exception) { Message = message; Exception = exception; }
public XipErrorMessage (string message, Exception exception) : this (message, ExceptionNode.Create (exception)) { }
public XipErrorMessage (Exception exception) : this (null, ExceptionNode.Create (exception)) { }
public XipErrorMessage (ExceptionNode exception) : this (null, exception) { }
public async Task RunAsync( Compilation compilation, CancellationToken cancellationToken = default(CancellationToken)) { foreach (var assembly in new AssemblyDefinition [] { compilation.ExecutableAssembly } .Concat(compilation.References ?? new AssemblyDefinition [] { })) { agent.LoadExternalDependencies(null, assembly?.ExternalDependencies); } Exception evaluationException = null; var result = new Evaluation { RequestId = compilation.MessageId, CodeCellId = compilation.CodeCellId, Phase = EvaluationPhase.Compiled }; if (compilation?.ExecutableAssembly?.Content.PEImage != null) { result.Compilation = compilation; } loadedAssemblies = new List <AssemblyDefinition> (); var savedStdout = Console.Out; var savedStderr = Console.Error; var capturedOutputWriter = new CapturedOutputWriter(compilation.CodeCellId); Console.SetOut(capturedOutputWriter.StandardOutput); Console.SetError(capturedOutputWriter.StandardError); capturedOutputWriter.SegmentCaptured += CapturedOutputWriter_SegmentCaptured; var stopwatch = new Stopwatch(); currentRunThread = Thread.CurrentThread; currentRunThread.CurrentCulture = InteractiveCulture.CurrentCulture; currentRunThread.CurrentUICulture = InteractiveCulture.CurrentUICulture; initializedAgentIntegration = false; try { // We _only_ want to capture exceptions from user-code here but // allow our own bugs to propagate out to the normal exception // handling. The only reason we capture these exceptions is in // case anything has been written to stdout/stderr by user-code // before the exception was raised... we still want to send that // captured output back to the client for rendering. stopwatch.Start(); result.Result = await CoreRunAsync(compilation, cancellationToken); } catch (AggregateException e) when(e.InnerExceptions?.Count == 1) { evaluationException = e; // the Roslyn-emitted script delegates are async, so all exceptions // raised within a delegate should be AggregateException; if there's // just one inner exception, unwind it since the async nature of the // script delegates is a REPL implementation detail. result.Exception = ExceptionNode.Create(e.InnerExceptions [0]); } catch (ThreadAbortException e) { evaluationException = e; result.Interrupted = true; Thread.ResetAbort(); } catch (ThreadInterruptedException e) { evaluationException = e; result.Interrupted = true; } catch (Exception e) { evaluationException = e; result.Exception = ExceptionNode.Create(e); } finally { stopwatch.Stop(); currentRunThread = null; result.Phase = EvaluationPhase.Evaluated; evaluations.Observers.OnNext(result); capturedOutputWriter.SegmentCaptured -= CapturedOutputWriter_SegmentCaptured; Console.SetOut(savedStdout); Console.SetError(savedStderr); } result.EvaluationDuration = stopwatch.Elapsed; // an exception in PrepareResult should not be explicitly caught // here (see above) since it'll be handled at a higher level and can be // flagged as being a bug in our code since this method should never throw. result.Result = agent.RepresentationManager.Prepare(result.Result); result.InitializedAgentIntegration = initializedAgentIntegration; result.LoadedAssemblies = loadedAssemblies.ToArray(); result.CultureLCID = InteractiveCulture.CurrentCulture.LCID; result.UICultureLCID = InteractiveCulture.CurrentUICulture.LCID; result.Phase = EvaluationPhase.Represented; evaluations.Observers.OnNext(result); if (evaluationException != null) { evaluations.Observers.OnError(evaluationException); } agent.PublishEvaluation(result); result.Phase = EvaluationPhase.Completed; evaluations.Observers.OnNext(result); }
async Task <CodeCellEvaluationStatus> CoreEvaluateCodeCellAsync( CodeCellState codeCellState, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken = ClientSession.CancellationToken.LinkWith(cancellationToken); if (!ClientSession.Agent.IsConnected || ClientSession.CompilationWorkspace == null) { codeCellState.View.IsEvaluating = false; codeCellState.View.HasErrorDiagnostics = true; codeCellState.View.RenderDiagnostic(new InteractiveDiagnostic( DiagnosticSeverity.Error, "Cannot evaluate: not connected to agent.")); return(CodeCellEvaluationStatus.Disconnected); } CodeAnalysis.Compilation compilation = null; ExceptionNode exception = null; bool agentTerminatedWhileEvaluating = false; try { compilation = await ClientSession.CompilationWorkspace.GetSubmissionCompilationAsync( codeCellState.DocumentId, new EvaluationEnvironment (ClientSession.WorkingDirectory), cancellationToken); var integrationAssemblies = compilation .References .Where(ra => ra.HasIntegration) .ToArray(); if (integrationAssemblies.Length > 0) { await ClientSession.Agent.Api.LoadAssembliesAsync( ClientSession.CompilationWorkspace.EvaluationContextId, integrationAssemblies); } foreach (var dependency in ClientSession.CompilationWorkspace.WebDependencies) { if (ClientSession.AddWebResource(dependency.Location, out var guid)) { await LoadWorkbookDependencyAsync(guid + dependency.Location.Extension); } } } catch (Exception e) { exception = ExceptionNode.Create(e); } var diagnostics = ClientSession.CompilationWorkspace.CurrentSubmissionDiagnostics.Filter(); codeCellState.View.HasErrorDiagnostics = diagnostics.HasErrors; foreach (var diagnostic in diagnostics) { codeCellState.View.RenderDiagnostic((InteractiveDiagnostic)diagnostic); } try { if (compilation != null) { codeCellState.LastEvaluationRequestId = compilation.MessageId; codeCellState.IsResultAnExpression = compilation.IsResultAnExpression; await ClientSession.Agent.Api.EvaluateAsync( compilation, cancellationToken); } } catch (XipErrorMessageException e) { exception = e.XipErrorMessage.Exception; } catch (Exception e) { Log.Error(TAG, "marking agent as terminated", e); agentTerminatedWhileEvaluating = true; codeCellState.View.HasErrorDiagnostics = true; codeCellState.View.RenderDiagnostic(new InteractiveDiagnostic( DiagnosticSeverity.Error, Catalog.GetString( "The application terminated during evaluation of this cell. " + "Run this cell manually to try again."))); } codeCellState.View.IsEvaluating = false; CodeCellEvaluationStatus evaluationStatus; if (exception != null) { codeCellState.View.RenderResult( CultureInfo.CurrentCulture, FilterException(exception), EvaluationResultHandling.Replace); evaluationStatus = CodeCellEvaluationStatus.EvaluationException; } else if (diagnostics.HasErrors) { return(CodeCellEvaluationStatus.ErrorDiagnostic); } else if (agentTerminatedWhileEvaluating) { evaluationStatus = CodeCellEvaluationStatus.Disconnected; } else { evaluationStatus = CodeCellEvaluationStatus.Success; } if (ClientSession.SessionKind != ClientSessionKind.Workbook) { codeCellState.Freeze(); } codeCellState.NotifyEvaluated(agentTerminatedWhileEvaluating); return(evaluationStatus); }
public ExceptionNode(TypeSpec type, string message, StackTrace stackTrace, ExceptionNode innerException);
/// <summary> /// Called on every representation to perform a normalization pass /// to convert many common object types to those that can be serialized /// in a normalized way. This provides a small safety layer as well, /// ensuring that we are only serializing objects that are safe/supported /// to do so across all agents*clients or explicitly declare themselves /// as an IRepresentationObject (an opt-in "contract" that says that /// clients should be able to deserialize it). /// </summary> /// <param name="obj">The object to normalize.</param> object Normalize(object obj) { switch (obj) { case null: return(null); case Representation originalRepresentation: // an object may be boxed in a Representation object if it has metadata // associated with it, such as whether the representation provider supports // "editing" via TryConvertFromRepresentation. We must still normalize the // value inside to ensure we can safely serialize it. If the value differs // after normalization, but is serializable, we re-box it with the normalized // value and the canEdit flag unset. var normalizedRepresentationValue = Normalize(originalRepresentation.Value); if (Equals(originalRepresentation.Value, normalizedRepresentationValue)) { return(obj); } if (normalizedRepresentationValue == null) { return(null); } return(originalRepresentation.With( normalizedRepresentationValue, canEdit: false)); } if (agentRepresentationProvider != null) { try { var normalized = agentRepresentationProvider.NormalizeRepresentation(obj); if (normalized != null) { return(normalized); } } catch (Exception e) { Log.Error(TAG, "Agent-builtin normalizer raised an exception", e); } } switch (obj) { case Enum enumValue: return(new EnumValue(enumValue)); case IInteractiveObject interactive: interactive.Handle = ObjectCache.Shared.GetHandle(interactive); return(interactive); case IRepresentationObject _: return(obj); case ISerializableObject iserializableObject when currentPreparePassAllowsISerializableObject: return((JsonPayload)iserializableObject.SerializeToString()); case IFallbackRepresentationObject _: return(obj); case Exception exception: return(ExceptionNode.Create(exception)); case MemberInfo memberInfo: try { var remoteMemberInfo = TypeMember.Create(memberInfo); if (remoteMemberInfo != null) { return(remoteMemberInfo); } } catch (Exception e) { Log.Warning(TAG, "unable to create TypeMember from MemberInfo", e); } return(null); case TimeSpan _: case Guid _: return(obj); case IntPtr intptr: return(new WordSizedNumber( obj, WordSizedNumberFlags.Pointer | WordSizedNumberFlags.Signed, (ulong)intptr)); case UIntPtr uintptr: return(new WordSizedNumber( obj, WordSizedNumberFlags.Pointer, (ulong)uintptr)); default: if (Type.GetTypeCode(obj.GetType()) != TypeCode.Object) { return(obj); } if (obj is byte []) { return(obj); } return(null); } }