chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Util;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets <see cref="ClrBubbledException"/> instances
|
||||
/// </summary>
|
||||
public class ClrBubbledExceptionInterpreter : SystemExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public override int Order => int.MaxValue - 1;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception. f
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public override bool CanInterpret(Exception exception) => exception?.GetType() == typeof(ClrBubbledException);
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public override Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var pe = (ClrBubbledException)exception;
|
||||
var sanitized = base.Interpret(exception, innerInterpreter);
|
||||
var inner = sanitized.InnerException ?? sanitized;
|
||||
|
||||
return new Exception(pe.Message + PythonUtil.PythonExceptionStackParser(pe.PythonTraceback), inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets <see cref="DllNotFoundPythonExceptionInterpreter"/> instances
|
||||
/// </summary>
|
||||
public class DllNotFoundPythonExceptionInterpreter : IExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public int Order => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public bool CanInterpret(Exception exception)
|
||||
{
|
||||
return
|
||||
exception?.GetType() == typeof(DllNotFoundException) &&
|
||||
exception.Message.Contains("python");
|
||||
}
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var dnfe = (DllNotFoundException)exception;
|
||||
|
||||
var startIndex = dnfe.Message.IndexOfInvariant("python");
|
||||
var length = Math.Min(dnfe.Message.Length - startIndex, 10);
|
||||
var dllName = dnfe.Message.Substring(startIndex, length);
|
||||
|
||||
length = dllName.IndexOfInvariant('\'');
|
||||
if (length > 0)
|
||||
{
|
||||
dllName = dllName.Substring(0, length);
|
||||
}
|
||||
|
||||
var platform = Environment.OSVersion.Platform.ToString();
|
||||
var message = Messages.DllNotFoundPythonExceptionInterpreter.DynamicLinkLibraryNotFound(dllName, platform);
|
||||
return new DllNotFoundException(message, dnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using QuantConnect.Interfaces;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines an exception interpreter. Interpretations are invoked on <see cref="IAlgorithm.RunTimeError"/>
|
||||
/// </summary>
|
||||
public interface IExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that a class that implements this interface should be called
|
||||
/// </summary>
|
||||
int Order { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
bool CanInterpret(Exception exception);
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.
|
||||
/// This provides a link back allowing the inner exceptions to be interpreted using the interpreters
|
||||
/// configured in the <see cref="IExceptionInterpreter"/>. Individual implementations *may* ignore
|
||||
/// this value if required.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Python.Runtime;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets <see cref="InvalidTokenPythonExceptionInterpreter"/> instances
|
||||
/// </summary>
|
||||
public class InvalidTokenPythonExceptionInterpreter : PythonExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public override int Order => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public override bool CanInterpret(Exception exception)
|
||||
{
|
||||
return base.CanInterpret(exception) &&
|
||||
(exception.Message.Contains(Messages.InvalidTokenPythonExceptionInterpreter.InvalidTokenExpectedSubstring, StringComparison.InvariantCultureIgnoreCase)
|
||||
|| exception.Message.Contains(Messages.InvalidTokenPythonExceptionInterpreter.NotPermittedExpectedSubstring, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public override Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var pe = (PythonException)exception;
|
||||
return new Exception(Messages.InvalidTokenPythonExceptionInterpreter.InterpretException(pe), pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Util;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets <see cref="KeyErrorPythonExceptionInterpreter"/> instances
|
||||
/// </summary>
|
||||
public class KeyErrorPythonExceptionInterpreter : PythonExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public override int Order => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public override bool CanInterpret(Exception exception)
|
||||
{
|
||||
var pythonException = exception as PythonException;
|
||||
if (pythonException == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
using (Py.GIL())
|
||||
{
|
||||
return base.CanInterpret(exception) &&
|
||||
pythonException.Type.Name.Contains("KeyError", StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public override Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var pe = (PythonException)exception;
|
||||
|
||||
var key = string.Empty;
|
||||
if (pe.Message.Contains('[', StringComparison.InvariantCulture))
|
||||
{
|
||||
key = pe.Message.GetStringBetweenChars('[', ']');
|
||||
}
|
||||
else if (pe.Message.Contains('\'', StringComparison.InvariantCulture))
|
||||
{
|
||||
key = pe.Message.GetStringBetweenChars('\'', '\'');
|
||||
}
|
||||
var message = Messages.KeyErrorPythonExceptionInterpreter.KeyNotFoundInCollection(key);
|
||||
|
||||
message += PythonUtil.PythonExceptionStackParser(pe.StackTrace);
|
||||
|
||||
return new KeyNotFoundException(message, pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Util;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets <see cref="NoMethodMatchPythonExceptionInterpreter"/> instances
|
||||
/// </summary>
|
||||
public class NoMethodMatchPythonExceptionInterpreter : PythonExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public override int Order => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public override bool CanInterpret(Exception exception)
|
||||
{
|
||||
return base.CanInterpret(exception) &&
|
||||
exception.Message.Contains(Messages.NoMethodMatchPythonExceptionInterpreter.NoMethodMatchExpectedSubstring);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public override Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var pe = (PythonException)exception;
|
||||
|
||||
var methodName = GetMethodName(pe.Message);
|
||||
var message = Messages.NoMethodMatchPythonExceptionInterpreter.AttemptedToAccessMethodThatDoesNotExist(methodName);
|
||||
|
||||
var overloadsHint = GetOverloadsHint(pe.Message);
|
||||
if (!string.IsNullOrEmpty(overloadsHint))
|
||||
{
|
||||
message += $" {overloadsHint}";
|
||||
}
|
||||
|
||||
message += PythonUtil.PythonExceptionStackParser(pe.StackTrace);
|
||||
|
||||
return new MissingMethodException(message, pe);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the name of the method that failed to resolve from the Python exception message.
|
||||
/// The message has the form: "No method matches given arguments for {methodName}: ({argumentTypes})",
|
||||
/// so the method name sits between the "for " keyword and the following ":".
|
||||
/// </summary>
|
||||
private static string GetMethodName(string exceptionMessage)
|
||||
{
|
||||
const string forKeyword = "for ";
|
||||
var forIndex = exceptionMessage.IndexOfInvariant(forKeyword);
|
||||
if (forIndex == -1)
|
||||
{
|
||||
// Unexpected format, fall back to the whole message
|
||||
return exceptionMessage.Trim();
|
||||
}
|
||||
|
||||
var methodNameStart = forIndex + forKeyword.Length;
|
||||
var colonIndex = exceptionMessage.IndexOf(':', methodNameStart);
|
||||
var methodName = colonIndex > methodNameStart
|
||||
? exceptionMessage.Substring(methodNameStart, colonIndex - methodNameStart)
|
||||
: exceptionMessage.Substring(methodNameStart);
|
||||
|
||||
return methodName.Trim();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the candidate-signatures hint pythonnet appends to the binding-failure
|
||||
/// message ("The expected signature is:" or "The following overloads are available:"
|
||||
/// followed by the signatures), so the interpreted message can keep it.
|
||||
/// </summary>
|
||||
private static string GetOverloadsHint(string exceptionMessage)
|
||||
{
|
||||
var hintIndex = exceptionMessage.IndexOfInvariant("The expected signature is:");
|
||||
if (hintIndex == -1)
|
||||
{
|
||||
hintIndex = exceptionMessage.IndexOfInvariant("The following overloads are available:");
|
||||
}
|
||||
|
||||
return hintIndex == -1 ? null : exceptionMessage.Substring(hintIndex).Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Util;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets <see cref="PythonExceptionInterpreter"/> instances
|
||||
/// </summary>
|
||||
public class PythonExceptionInterpreter : IExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public virtual int Order => int.MaxValue - 1;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception. f
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public virtual bool CanInterpret(Exception exception) => exception?.GetType() == typeof(PythonException);
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public virtual Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var pe = (PythonException)exception;
|
||||
|
||||
return new Exception(PythonUtil.PythonExceptionParser(pe), pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using QuantConnect.Scheduling;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets <see cref="ScheduledEventException"/> instances
|
||||
/// </summary>
|
||||
public class ScheduledEventExceptionInterpreter : IExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public int Order => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public bool CanInterpret(Exception exception) => exception?.GetType() == typeof(ScheduledEventException);
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.
|
||||
/// This provides a link back allowing the inner exceptions to be interpreted using the interpreters
|
||||
/// configured in the <see cref="IExceptionInterpreter"/>. Individual implementations *may* ignore
|
||||
/// this value if required.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var see = (ScheduledEventException) exception;
|
||||
|
||||
var inner = innerInterpreter.Interpret(see.InnerException, innerInterpreter);
|
||||
|
||||
// prepend the scheduled event name
|
||||
var message = exception.Message;
|
||||
if (!message.Contains(see.ScheduledEventName))
|
||||
{
|
||||
message = Messages.ScheduledEventExceptionInterpreter.ScheduledEventName(see.ScheduledEventName);
|
||||
}
|
||||
|
||||
return new ScheduledEventException(see.ScheduledEventName, message, inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using QuantConnect.Util;
|
||||
using System.Reflection;
|
||||
using QuantConnect.Logging;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets exceptions using the configured interpretations
|
||||
/// </summary>
|
||||
public class StackExceptionInterpreter : IExceptionInterpreter
|
||||
{
|
||||
private readonly List<IExceptionInterpreter> _interpreters;
|
||||
|
||||
/// <summary>
|
||||
/// Stack interpreter instance
|
||||
/// </summary>
|
||||
public static readonly Lazy<StackExceptionInterpreter> Instance = new Lazy<StackExceptionInterpreter>(
|
||||
() => StackExceptionInterpreter.CreateFromAssemblies());
|
||||
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public int Order => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StackExceptionInterpreter"/> class
|
||||
/// </summary>
|
||||
/// <param name="interpreters">The interpreters to use</param>
|
||||
public StackExceptionInterpreter(IEnumerable<IExceptionInterpreter> interpreters)
|
||||
{
|
||||
_interpreters = interpreters.OrderBy(x => x.Order).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the interpreters loaded into this instance
|
||||
/// </summary>
|
||||
public IEnumerable<IExceptionInterpreter> Interpreters => _interpreters;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public bool CanInterpret(Exception exception)
|
||||
{
|
||||
return _interpreters.Any(interpreter => interpreter.CanInterpret(exception));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.
|
||||
/// This provides a link back allowing the inner exceptions to be interpreted using the intepretators
|
||||
/// configured in the <see cref="StackExceptionInterpreter"/>. Individual implementations *may* ignore
|
||||
/// this value if required.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter = null)
|
||||
{
|
||||
if (exception == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var interpreter in _interpreters)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (interpreter.CanInterpret(exception))
|
||||
{
|
||||
// use this instance to interpret inner exceptions as well, unless one was specified
|
||||
return interpreter.Interpret(exception, innerInterpreter ?? this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
Log.Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combines the exception messages from this exception and all inner exceptions.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to create a collated message from</param>
|
||||
/// <returns>The collate exception message</returns>
|
||||
public string GetExceptionMessageHeader(Exception exception)
|
||||
{
|
||||
return string.Join(" ", InnersAndSelf(exception).Select(e => e.Message));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="StackExceptionInterpreter"/> by loading implementations with default constructors from the specified assemblies
|
||||
/// </summary>
|
||||
/// <returns>A new <see cref="StackExceptionInterpreter"/> containing interpreters from the specified assemblies</returns>
|
||||
public static StackExceptionInterpreter CreateFromAssemblies()
|
||||
{
|
||||
var interpreters =
|
||||
// type implements IExceptionInterpreter
|
||||
from type in Composer.Instance.GetExportedTypes<IExceptionInterpreter>()
|
||||
// ignore non-public and non-instantiable abstract types
|
||||
// type has default parameterless ctor
|
||||
where type.IsPublic && !type.IsAbstract && type.GetConstructor([]) != null
|
||||
// provide guarantee of deterministic ordering
|
||||
orderby type.FullName
|
||||
select (IExceptionInterpreter) Activator.CreateInstance(type);
|
||||
|
||||
var stackExceptionInterpreter = new StackExceptionInterpreter(interpreters);
|
||||
|
||||
foreach (var interpreter in stackExceptionInterpreter.Interpreters)
|
||||
{
|
||||
Log.Debug(Messages.StackExceptionInterpreter.LoadedExceptionInterpreter(interpreter));
|
||||
}
|
||||
|
||||
return stackExceptionInterpreter;
|
||||
}
|
||||
|
||||
private IEnumerable<Exception> InnersAndSelf(Exception exception)
|
||||
{
|
||||
yield return exception;
|
||||
while (exception.InnerException != null)
|
||||
{
|
||||
exception = exception.InnerException;
|
||||
yield return exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Base handler that will try get an exception file and line
|
||||
/// </summary>
|
||||
public class SystemExceptionInterpreter : IExceptionInterpreter
|
||||
{
|
||||
private static Regex FileAndLineRegex = new ("(\\w+.cs:line \\d+)", RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public virtual int Order => int.MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception. f
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public virtual bool CanInterpret(Exception exception) => true;
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public virtual Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var sanitized = new SanitizedException(exception.Message, exception.StackTrace);
|
||||
|
||||
if (!TryGetLineAndFile(exception.StackTrace, out var fileAndLine))
|
||||
{
|
||||
return sanitized;
|
||||
}
|
||||
return new Exception(exception.Message + fileAndLine, innerException: sanitized);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to get the file and line from a C# stacktrace
|
||||
/// </summary>
|
||||
public static bool TryGetLineAndFile(string stackTrace, out string fileAndLine)
|
||||
{
|
||||
fileAndLine = null;
|
||||
if (stackTrace != null)
|
||||
{
|
||||
var match = FileAndLineRegex.Match(stackTrace);
|
||||
if (match.Success)
|
||||
{
|
||||
foreach (Match lineCapture in match.Captures)
|
||||
{
|
||||
fileAndLine = $" in {lineCapture.Groups[1].Value}" ;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private class SanitizedException : Exception
|
||||
{
|
||||
private readonly string _message;
|
||||
private readonly string _stackTrace;
|
||||
|
||||
public override string Message => _message;
|
||||
public override string StackTrace => _stackTrace;
|
||||
|
||||
public SanitizedException(string message, string stackTrace)
|
||||
{
|
||||
_message = message;
|
||||
_stackTrace = Logging.Log.ClearLeanPaths(stackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Util;
|
||||
|
||||
namespace QuantConnect.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interprets <see cref="UnsupportedOperandPythonExceptionInterpreter"/> instances
|
||||
/// </summary>
|
||||
public class UnsupportedOperandPythonExceptionInterpreter : PythonExceptionInterpreter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the order that an instance of this class should be called
|
||||
/// </summary>
|
||||
public override int Order => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this interpreter should be applied to the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to check</param>
|
||||
/// <returns>True if the exception can be interpreted, false otherwise</returns>
|
||||
public override bool CanInterpret(Exception exception)
|
||||
{
|
||||
return base.CanInterpret(exception) &&
|
||||
exception.Message.Contains(Messages.UnsupportedOperandPythonExceptionInterpreter.UnsupportedOperandTypeExpectedSubstring);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interprets the specified exception into a new exception
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to be interpreted</param>
|
||||
/// <param name="innerInterpreter">An interpreter that should be applied to the inner exception.</param>
|
||||
/// <returns>The interpreted exception</returns>
|
||||
public override Exception Interpret(Exception exception, IExceptionInterpreter innerInterpreter)
|
||||
{
|
||||
var pe = (PythonException)exception;
|
||||
|
||||
var types = pe.Message.Split(':')[1].Trim();
|
||||
var message = Messages.UnsupportedOperandPythonExceptionInterpreter.InvalidObjectTypesForOperation(types);
|
||||
message += PythonUtil.PythonExceptionStackParser(pe.StackTrace);
|
||||
|
||||
return new Exception(message, pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user