mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-11 21:27:01 -04:00
try to get stack traces for InternalErrors, it doesn't work yet for errors caught with OnExceptionInMainLoop, because they are rethrown.
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1260 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -9,6 +9,10 @@
|
|||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <util/error.hpp>
|
#include <util/error.hpp>
|
||||||
#include <cli/text_io_handler.hpp>
|
#include <cli/text_io_handler.hpp>
|
||||||
|
#include <cli/text_io_handler.hpp>
|
||||||
|
#if wxUSE_STACKWALKER
|
||||||
|
#include <wx/stackwalk.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
DECLARE_TYPEOF_COLLECTION(ScriptParseError);
|
DECLARE_TYPEOF_COLLECTION(ScriptParseError);
|
||||||
|
|
||||||
@@ -43,6 +47,85 @@ String Error::what() const {
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Stolen from wx/appbase.cpp
|
||||||
|
// we can't just call it, because of static linkage
|
||||||
|
#if wxUSE_STACKWALKER
|
||||||
|
String get_stack_trace() {
|
||||||
|
wxString stackTrace;
|
||||||
|
|
||||||
|
class StackDumper : public wxStackWalker {
|
||||||
|
public:
|
||||||
|
StackDumper() {}
|
||||||
|
|
||||||
|
const wxString& GetStackTrace() const { return m_stackTrace; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnStackFrame(const wxStackFrame& frame) {
|
||||||
|
m_stackTrace << wxString::Format(_("[%02d] "), frame.GetLevel());
|
||||||
|
|
||||||
|
wxString name = frame.GetName();
|
||||||
|
if ( !name.empty() ) {
|
||||||
|
m_stackTrace << wxString::Format(_("%-40s"), name.c_str());
|
||||||
|
} else {
|
||||||
|
m_stackTrace << wxString::Format(
|
||||||
|
_("%p"),
|
||||||
|
(void*)frame.GetAddress()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( frame.HasSourceLocation() ) {
|
||||||
|
m_stackTrace << _('\t')
|
||||||
|
<< frame.GetFileName()
|
||||||
|
<< _(':')
|
||||||
|
<< (unsigned int)frame.GetLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stackTrace << _('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxString m_stackTrace;
|
||||||
|
};
|
||||||
|
|
||||||
|
StackDumper dump;
|
||||||
|
dump.Walk(2); // don't show InternalError() call itself
|
||||||
|
stackTrace = dump.GetStackTrace();
|
||||||
|
|
||||||
|
// don't show more than maxLines or we could get a dialog too tall to be
|
||||||
|
// shown on screen: 20 should be ok everywhere as even with 15 pixel high
|
||||||
|
// characters it is still only 300 pixels...
|
||||||
|
static const int maxLines = 20;
|
||||||
|
const int count = stackTrace.Freq(wxT('\n'));
|
||||||
|
for ( int i = 0; i < count - maxLines; i++ )
|
||||||
|
stackTrace = stackTrace.BeforeLast(wxT('\n'));
|
||||||
|
|
||||||
|
return stackTrace;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
String get_stack_trace() {
|
||||||
|
return _(""); // not supported
|
||||||
|
}
|
||||||
|
#endif // wxUSE_STACKWALKER
|
||||||
|
|
||||||
|
InternalError::InternalError(const String& str)
|
||||||
|
: Error(
|
||||||
|
_("An internal error occured:\n\n") +
|
||||||
|
str + _("\n")
|
||||||
|
_("Please save your work (use 'save as' to so you don't overwrite things)\n")
|
||||||
|
_("and restart Magic Set Editor.\n\n")
|
||||||
|
_("You should leave a bug report on http://magicseteditor.sourceforge.net/\n")
|
||||||
|
_("Press Ctrl+C to copy this message to the clipboard.")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// add a stacktrace
|
||||||
|
const String stack_trace = get_stack_trace();
|
||||||
|
if (!stack_trace.empty()) {
|
||||||
|
message << _("\n\nCall stack:\n") << stack_trace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Parse errors
|
// ----------------------------------------------------------------------------- : Parse errors
|
||||||
|
|
||||||
ScriptParseError::ScriptParseError(size_t pos, int line, const String& filename, const String& error)
|
ScriptParseError::ScriptParseError(size_t pos, int line, const String& filename, const String& error)
|
||||||
|
|||||||
+5
-4
@@ -27,7 +27,7 @@ class Error {
|
|||||||
/// Return the error message
|
/// Return the error message
|
||||||
virtual String what() const;
|
virtual String what() const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
String message; ///< The error message
|
String message; ///< The error message
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,9 +35,7 @@ class Error {
|
|||||||
/// Internal errors
|
/// Internal errors
|
||||||
class InternalError : public Error {
|
class InternalError : public Error {
|
||||||
public:
|
public:
|
||||||
inline InternalError(const String& str)
|
InternalError(const String& str);
|
||||||
: Error(_ERROR_1_("internal error", str.c_str()))
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : File errors
|
// ----------------------------------------------------------------------------- : File errors
|
||||||
@@ -148,6 +146,9 @@ void handle_warning(const String& w, bool now = true);
|
|||||||
/** Should be called repeatedly (e.g. in an onIdle event handler) */
|
/** Should be called repeatedly (e.g. in an onIdle event handler) */
|
||||||
void handle_pending_errors();
|
void handle_pending_errors();
|
||||||
|
|
||||||
|
/// Make a stack trace for use in InternalErrors
|
||||||
|
String get_stack_trace();
|
||||||
|
|
||||||
/// Catch all types of errors, and pass then to handle_error
|
/// Catch all types of errors, and pass then to handle_error
|
||||||
#define CATCH_ALL_ERRORS(handle_now) \
|
#define CATCH_ALL_ERRORS(handle_now) \
|
||||||
catch (const Error& e) { \
|
catch (const Error& e) { \
|
||||||
|
|||||||
Reference in New Issue
Block a user