コード例 #1
0
        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);
        }
コード例 #2
0
 public GetMemberValueError(Exception exception = null)
 {
     if (exception != null)
     {
         Exception = ExceptionNode.Create(exception);
     }
 }
コード例 #3
0
 /// <summary>Развертывание информации в ExceptionNode из полученного экземпляра обьекта</summary>
 public static ExceptionNode DispatchNode(object obj)
 {
     ExceptionNode node = new ExceptionNode();
     //TODO: дописать разбор объекта
     node.Value = obj.ToString();
     return node;
 }
コード例 #4
0
 public ExceptionNode(
     TypeSpec type,
     string message,
     StackTrace stackTrace,
     ExceptionNode innerException)
 {
     Type           = type;
     Message        = message;
     StackTrace     = stackTrace;
     InnerException = innerException;
 }
コード例 #5
0
        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)));
        }
コード例 #6
0
        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);
            }
        }
コード例 #7
0
        /// <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);
            }
        }
コード例 #8
0
        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>");
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
 GetMemberValueError(ExceptionNode exception)
 => Exception = exception;
コード例 #11
0
        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);
        }
コード例 #12
0
 public virtual void VisitExceptionNode(ExceptionNode exception);
コード例 #13
0
 public XipErrorMessage (string message, ExceptionNode exception)
 {
     Message = message;
     Exception = exception;
 }
コード例 #14
0
 public XipErrorMessage (string message, Exception exception)
     : this (message, ExceptionNode.Create (exception))
 {
 }
コード例 #15
0
 public XipErrorMessage (Exception exception)
     : this (null, ExceptionNode.Create (exception))
 {
 }
コード例 #16
0
 public XipErrorMessage (ExceptionNode exception)
     : this (null, exception)
 {
 }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
 public ExceptionNode(TypeSpec type, string message, StackTrace stackTrace, ExceptionNode innerException);
コード例 #20
0
        /// <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);
            }
        }