// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Runtime.Serialization;
using Microsoft.ClearScript.Util;
namespace Microsoft.ClearScript
{
///
/// The exception that is thrown when an error occurs during script execution or script object access.
///
[Serializable]
public class ScriptEngineException : InvalidOperationException, IScriptEngineException
{
private readonly string engineName;
private const string engineNameItemName = "ScriptEngineName";
private readonly string errorDetails;
private const string errorDetailsItemName = "ScriptErrorDetails";
private readonly bool isFatal;
private const string isFatalItemName = "IsFatal";
private readonly bool executionStarted;
private const string executionStartedItemName = "ExecutionStarted";
private readonly object scriptException;
private const string defaultMessage = "An error occurred during script execution";
#region constructors
///
/// Initializes a new instance.
///
public ScriptEngineException()
: base(defaultMessage)
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
///
/// Initializes a new with the specified error message.
///
/// The error message.
public ScriptEngineException(string message)
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage))
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
///
/// Initializes a new with the specified error message and nested exception.
///
/// The error message.
/// The exception that caused the current exception to be thrown.
public ScriptEngineException(string message, Exception innerException)
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage), innerException)
{
// ReSharper disable once RedundantBaseQualifier
errorDetails = base.Message;
}
///
/// Initializes a new with serialized data.
///
/// The object that holds the serialized data.
/// The contextual information about the source or destination.
protected ScriptEngineException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
engineName = info.GetString(engineNameItemName);
errorDetails = info.GetString(errorDetailsItemName);
isFatal = info.GetBoolean(isFatalItemName);
executionStarted = info.GetBoolean(executionStartedItemName);
}
internal ScriptEngineException(string engineName, string message, string errorDetails, int errorCode, bool isFatal, bool executionStarted, object scriptException, Exception innerException)
: base(MiscHelpers.EnsureNonBlank(message, defaultMessage), innerException)
{
this.engineName = engineName;
// ReSharper disable once RedundantBaseQualifier
this.errorDetails = MiscHelpers.EnsureNonBlank(errorDetails, base.Message);
this.isFatal = isFatal;
this.executionStarted = executionStarted;
this.scriptException = scriptException;
if (errorCode != 0)
{
HResult = errorCode;
}
}
#endregion
#region IScriptEngineException implementation
///
/// Gets an HRESULT error code if one is available, zero otherwise.
///
int IScriptEngineException.HResult
{
get { return HResult; }
}
///
/// Gets the name associated with the script engine instance.
///
public string EngineName
{
get { return engineName; }
}
///
/// Gets a detailed error message if one is available, null otherwise.
///
public string ErrorDetails
{
get { return errorDetails; }
}
///
/// Gets a value that indicates whether the exception represents a fatal error.
///
public bool IsFatal
{
get { return isFatal; }
}
///
/// Gets a value that indicates whether script code execution had started before the current exception was thrown.
///
public bool ExecutionStarted
{
get { return executionStarted; }
}
///
/// Gets the script exception that caused the current exception to be thrown, or null if one was not specified.
///
public dynamic ScriptException
{
get { return scriptException; }
}
#endregion
#region Object overrides
///
/// Returns a string that represents the current exception.
///
/// A string that represents the current exception.
public override string ToString()
{
var result = base.ToString();
if (!string.IsNullOrEmpty(errorDetails) && (errorDetails != Message))
{
var details = " " + errorDetails.Replace("\n", "\n ");
result += "\n --- Script error details follow ---\n" + details;
}
return result;
}
#endregion
#region InvalidOperationException overrides
///
/// Populates a with the data needed to serialize the target object.
///
/// The to populate with data.
/// The destination (see ) for this serialization.
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue(engineNameItemName, engineName);
info.AddValue(errorDetailsItemName, errorDetails);
info.AddValue(isFatalItemName, isFatal);
info.AddValue(executionStartedItemName, executionStarted);
}
#endregion
}
}