/********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System.Management.Automation.Language; using System.Runtime.Serialization; #if !CORECLR using System.Security.Permissions; #else // Use stub for SerializableAttribute, SecurityPermissionAttribute and ISerializable related types. using Microsoft.PowerShell.CoreClr.Stubs; #endif namespace System.Management.Automation { /// /// RuntimeException is the base class for exceptions likely to occur /// while a Monad command is running. /// /// /// Monad scripts can trap RuntimeException using the /// "trap (exceptionclass) {handler}" script construct. /// /// Instances of this exception class are usually generated by the /// Monad Engine. It is unusual for code outside the Monad Engine /// to create an instance of this class. /// [Serializable] public class RuntimeException : SystemException, IContainsErrorRecord { #region ctor /// /// Initializes a new instance of the RuntimeException class. /// /// constructed object public RuntimeException() : base() { } #region Serialization /// /// Initializes a new instance of the RuntimeException class /// using data serialized via /// /// /// serialization information /// streaming context /// constructed object protected RuntimeException(SerializationInfo info, StreamingContext context) : base(info, context) { _errorId = info.GetString("ErrorId"); _errorCategory = (ErrorCategory)info.GetInt32("ErrorCategory"); } /// /// Serializer for /// /// serialization information /// streaming context [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] public override void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) { throw new PSArgumentNullException("info"); } base.GetObjectData(info, context); info.AddValue("ErrorId", _errorId); info.AddValue("ErrorCategory", (Int32)_errorCategory); } #endregion Serialization /// /// Initializes a new instance of the RuntimeException class. /// /// /// constructed object public RuntimeException(string message) : base(message) { } /// /// Initializes a new instance of the RuntimeException class. /// /// /// /// constructed object public RuntimeException(string message, Exception innerException) : base(message, innerException) { } /// /// Initializes a new instance of the RuntimeException class /// starting with an already populated error record. /// /// /// /// /// constructed object public RuntimeException(string message, Exception innerException, ErrorRecord errorRecord) : base(message, innerException) { _errorRecord = errorRecord; } internal RuntimeException(ErrorCategory errorCategory, InvocationInfo invocationInfo, IScriptExtent errorPosition, string errorIdAndResourceId, string message, Exception innerException) : base(message, innerException) { SetErrorCategory(errorCategory); SetErrorId(errorIdAndResourceId); if ((errorPosition == null) && (invocationInfo != null)) { errorPosition = invocationInfo.ScriptPosition; } if (invocationInfo == null) return; _errorRecord = new ErrorRecord( new ParentContainsErrorRecordException(this), _errorId, _errorCategory, _targetObject); _errorRecord.SetInvocationInfo(new InvocationInfo(invocationInfo.MyCommand, errorPosition)); } #endregion ctor #region ErrorRecord // If RuntimeException subclasses need to do more than change // the ErrorId, ErrorCategory and TargetObject, they can access // the ErrorRecord property and make changes directly. However, // not that calling SetErrorId, SetErrorCategory or SetTargetObject // will clean the cached ErrorRecord and erase any other changes, // so the ErrorId etc. should be set first. /// /// Additional information about the error /// /// /// /// Note that ErrorRecord.Exception is /// . /// public virtual ErrorRecord ErrorRecord { get { if (null == _errorRecord) { _errorRecord = new ErrorRecord( new ParentContainsErrorRecordException(this), _errorId, _errorCategory, _targetObject); } return _errorRecord; } } private ErrorRecord _errorRecord; private string _errorId = "RuntimeException"; private ErrorCategory _errorCategory = ErrorCategory.NotSpecified; private object _targetObject = null; /// /// Subclasses can use this method to set the ErrorId. /// Note that this will clear the cached ErrorRecord, so be sure /// to change this before writing to ErrorRecord.ErrorDetails /// or the like. /// /// per ErrorRecord constructors internal void SetErrorId(string errorId) { if (_errorId != errorId) { _errorId = errorId; _errorRecord = null; } } /// /// Subclasses can use this method to set the ErrorCategory. /// Note that this will clear the cached ErrorRecord, so be sure /// to change this before writing to ErrorRecord.ErrorDetails /// or the like. /// /// /// per ErrorRecord.CategoryInfo.Category /// internal void SetErrorCategory(ErrorCategory errorCategory) { if (_errorCategory != errorCategory) { _errorCategory = errorCategory; _errorRecord = null; } } /// /// Subclasses can use this method to set or update the TargetObject. /// This convenience function doesn't clobber the error record if it /// already exists... /// /// /// per ErrorRecord.TargetObject /// internal void SetTargetObject(object targetObject) { _targetObject = targetObject; if (_errorRecord != null) _errorRecord.SetTargetObject(targetObject); } #endregion ErrorRecord #region Internal internal static string RetrieveMessage(ErrorRecord errorRecord) { if (null == errorRecord) return ""; if (null != errorRecord.ErrorDetails && !String.IsNullOrEmpty(errorRecord.ErrorDetails.Message)) { return errorRecord.ErrorDetails.Message; } if (null == errorRecord.Exception) return ""; return errorRecord.Exception.Message; } internal static string RetrieveMessage(Exception e) { if (null == e) return ""; IContainsErrorRecord icer = e as IContainsErrorRecord; if (null == icer) return e.Message; ErrorRecord er = icer.ErrorRecord; if (null == er) return e.Message; ErrorDetails ed = er.ErrorDetails; if (null == ed) return e.Message; string detailsMessage = ed.Message; return (String.IsNullOrEmpty(detailsMessage)) ? e.Message : detailsMessage; } internal static Exception RetrieveException(ErrorRecord errorRecord) { if (null == errorRecord) return null; return errorRecord.Exception; } /// /// /// public bool WasThrownFromThrowStatement { get { return _thrownByThrowStatement; } set { _thrownByThrowStatement = value; if (_errorRecord != null) { RuntimeException exception = _errorRecord.Exception as RuntimeException; if (exception != null) { exception.WasThrownFromThrowStatement = value; } } } } private bool _thrownByThrowStatement; /// /// fix for BUG: Windows Out Of Band Releases: 906263 and 906264 /// The interpreter prompt CommandBaseStrings:InquireHalt /// should be suppressed when this flag is set. This will be set /// when this prompt has already occurred and Break was chosen, /// or for ActionPreferenceStopException in all cases. /// internal bool SuppressPromptInInterpreter { get { return _suppressPromptInInterpreter; } set { _suppressPromptInInterpreter = value; } } private bool _suppressPromptInInterpreter; #endregion Internal private Token _errorToken; internal Token ErrorToken { get { return _errorToken; } set { _errorToken = value; } } } // RuntimeException } // System.Management.Automation