// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/String.h"
#include "ManagedCLR/MTypes.h"
#include "Engine/Core/Log.h"
///
/// Represents errors that occur during script execution.
///
class FLAXENGINE_API MException
{
public:
///
/// Gets a message that describes the current exception.
///
String Message;
///
/// Gets a string representation of the immediate frames on the call stack.
///
String StackTrace;
///
/// Gets an inner exception. Null if not used.
///
MException* InnerException;
public:
#if USE_MONO
///
/// Initializes a new instance of the class.
///
/// The exception.
explicit MException(MonoException* exception)
: MException((MonoObject*)exception)
{
}
#endif
///
/// Initializes a new instance of the class.
///
/// The exception object.
explicit MException(MObject* exception);
///
/// Disposes a instance of the class.
///
~MException();
public:
///
/// Sends exception to the log.
///
/// The log message type.
/// Execution target name.
void Log(const LogType type, const Char* target)
{
// Log inner exceptions chain
auto inner = InnerException;
while (inner)
{
auto stackTrace = inner->StackTrace.HasChars() ? *inner->StackTrace : TEXT("");
Log::Logger::Write(LogType::Warning, String::Format(TEXT("Inner exception. {0}\nStack strace:\n{1}\n"), inner->Message, stackTrace));
inner = inner->InnerException;
}
// Send stack trace only to log file
auto stackTrace = StackTrace.HasChars() ? *StackTrace : TEXT("");
Log::Logger::Write(LogType::Warning, String::Format(TEXT("Exception has been thrown during {0}. {1}\nStack strace:\n{2}"), target, Message, stackTrace));
Log::Logger::Write(type, String::Format(TEXT("Exception has been thrown during {0}.\n{1}"), target, Message));
}
};