mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 15:06:32 +00:00
Add string messages to returned result codes to display to user
* Most of the main entry points that can fail with relevant reasons now has a way of specifying a message to return with it. This message can be displayed to the user to give more information or context about an error.
This commit is contained in:
@@ -577,8 +577,10 @@ void PythonContext::ProcessExtensionWork(std::function<void()> callback)
|
||||
PyGILState_Release(gil);
|
||||
}
|
||||
|
||||
bool PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extension)
|
||||
QString PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extension)
|
||||
{
|
||||
QString ret;
|
||||
|
||||
PyObject *sysobj = PyDict_GetItemString(main_dict, "sys");
|
||||
|
||||
PyObject *syspath = PyObject_GetAttrString(sysobj, "path");
|
||||
@@ -649,6 +651,7 @@ bool PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extension)
|
||||
if(mod == NULL)
|
||||
{
|
||||
qCritical() << "Failed to reload " << keystr;
|
||||
ret += tr("Failed to reload submodule '%1'\n").arg(keystr);
|
||||
reloadSuccess = false;
|
||||
break;
|
||||
}
|
||||
@@ -704,19 +707,28 @@ bool PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extension)
|
||||
else
|
||||
{
|
||||
qCritical() << "Internal error passing pyrenderdoc to extension register()";
|
||||
ret += tr("Internal error passing pyrenderdoc to extension register()\n");
|
||||
}
|
||||
|
||||
if(retval == NULL)
|
||||
{
|
||||
qCritical() << "register() function failed";
|
||||
ret += tr("register() function failed\n");
|
||||
ext = NULL;
|
||||
}
|
||||
|
||||
Py_XDECREF(retval);
|
||||
|
||||
if(ext)
|
||||
{
|
||||
int ret = PyModule_AddObject(ext, "pyrenderdoc", pyctx);
|
||||
int pyret = PyModule_AddObject(ext, "pyrenderdoc", pyctx);
|
||||
|
||||
if(ret != 0)
|
||||
if(pyret != 0)
|
||||
{
|
||||
qCritical() << "Couldn't set pyrenderdoc global in loaded module";
|
||||
ret += tr("Couldn't set pyrenderdoc global in loaded module\n");
|
||||
ext = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Py_XDECREF(pyctx);
|
||||
@@ -735,17 +747,26 @@ bool PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extension)
|
||||
{
|
||||
FetchException(typeStr, valueStr, finalLine, frames);
|
||||
|
||||
ret += lit("\n");
|
||||
|
||||
ret = ret.trimmed();
|
||||
|
||||
qCritical("Error importing extension module. %s: %s", typeStr.toUtf8().data(),
|
||||
valueStr.toUtf8().data());
|
||||
ret += tr("Error importing extension module. %1: %2\n\n").arg(typeStr).arg(valueStr);
|
||||
|
||||
if(!frames.isEmpty())
|
||||
{
|
||||
qCritical() << "Traceback (most recent call last):";
|
||||
ret += tr("Traceback (most recent call last):\n");
|
||||
for(const QString &f : frames)
|
||||
{
|
||||
QStringList lines = f.split(QLatin1Char('\n'));
|
||||
for(const QString &line : lines)
|
||||
qCritical("%s", line.toUtf8().data());
|
||||
{
|
||||
qCritical(" %s", line.toUtf8().data());
|
||||
ret += line + lit("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -757,7 +778,7 @@ bool PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extension)
|
||||
|
||||
current_global_handle = NULL;
|
||||
|
||||
return ext != NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PythonContext::ConvertPyArgs(const ExtensionCallbackData &data,
|
||||
@@ -833,10 +854,7 @@ void PythonContext::executeString(const QString &filename, const QString &source
|
||||
{
|
||||
if(!initialised())
|
||||
{
|
||||
emit exception(
|
||||
lit("SystemError"),
|
||||
tr("Python integration failed to initialise, see diagnostic log for more information."), -1,
|
||||
{});
|
||||
emit exception(lit("SystemError"), tr("Python integration failed to initialise."), -1, {});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -934,10 +952,7 @@ void PythonContext::setGlobal(const char *varName, const char *typeName, void *o
|
||||
{
|
||||
if(!initialised())
|
||||
{
|
||||
emit exception(
|
||||
lit("SystemError"),
|
||||
tr("Python integration failed to initialise, see diagnostic log for more information."), -1,
|
||||
{});
|
||||
emit exception(lit("SystemError"), tr("Python integration failed to initialise."), -1, {});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1142,10 +1157,7 @@ void PythonContext::setPyGlobal(const char *varName, PyObject *obj)
|
||||
{
|
||||
if(!initialised())
|
||||
{
|
||||
emit exception(
|
||||
lit("SystemError"),
|
||||
tr("Python integration failed to initialise, see diagnostic log for more information."), -1,
|
||||
{});
|
||||
emit exception(lit("SystemError"), tr("Python integration failed to initialise."), -1, {});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
static QStringList GetApplicationExtensionsPaths();
|
||||
static void ProcessExtensionWork(std::function<void()> callback);
|
||||
static bool LoadExtension(ICaptureContext &ctx, const rdcstr &extension);
|
||||
static QString LoadExtension(ICaptureContext &ctx, const rdcstr &extension);
|
||||
static void ConvertPyArgs(const ExtensionCallbackData &data,
|
||||
rdcarray<rdcpair<rdcstr, PyObject *>> &args);
|
||||
static void FreePyArgs(rdcarray<rdcpair<rdcstr, PyObject *>> &args);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
|
||||
%feature("python:tp_str") ResultDetails "result_str";
|
||||
%feature("python:tp_repr") ResultDetails "result_str";
|
||||
|
||||
// add some useful builtin functions for ResourceId
|
||||
%feature("python:tp_str") ResourceId "resid_str";
|
||||
%feature("python:tp_repr") ResourceId "resid_str";
|
||||
@@ -35,6 +38,22 @@ fail:
|
||||
} // %extend ResourceId
|
||||
|
||||
%wrapper %{
|
||||
static PyObject *result_str(PyObject *resid)
|
||||
{
|
||||
void *resptr = NULL;
|
||||
ResultDetails *result = NULL;
|
||||
int res = SWIG_ConvertPtr(resid, &resptr, SWIGTYPE_p_ResultDetails, 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "in method 'ResultDetails.str', ResultDetails is not correct type");
|
||||
}
|
||||
|
||||
result = (ResultDetails *)resptr;
|
||||
|
||||
return PyUnicode_FromFormat("<Result: '%s'>", result->Message().c_str());
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *resid_str(PyObject *resid)
|
||||
{
|
||||
void *resptr = NULL;
|
||||
|
||||
@@ -187,14 +187,14 @@ void RemoteHost::CheckStatus()
|
||||
{
|
||||
}
|
||||
|
||||
ReplayStatus RemoteHost::Connect(IRemoteServer **server)
|
||||
ResultDetails RemoteHost::Connect(IRemoteServer **server)
|
||||
{
|
||||
return ReplayStatus::Succeeded;
|
||||
return {ResultCode::Succeeded};
|
||||
}
|
||||
|
||||
ReplayStatus RemoteHost::Launch()
|
||||
ResultDetails RemoteHost::Launch()
|
||||
{
|
||||
return ReplayStatus::Succeeded;
|
||||
return {ResultCode::Succeeded};
|
||||
}
|
||||
|
||||
bool RemoteHost::IsServerRunning() const
|
||||
|
||||
@@ -155,6 +155,11 @@ VA_IGNORE_REST_OF_FILE
|
||||
%ignore StructuredChunkList::StructuredChunkList;
|
||||
%ignore StructuredChunkList::~StructuredChunkList;
|
||||
|
||||
// don't allow user code to create ResultDetails objects (they can't allocate the string)
|
||||
// or access the internal message, which we can't hide as ResultDetails must be POD.
|
||||
%ignore ResultDetails::ResultDetails;
|
||||
%ignore ResultDetails::internal_msg;
|
||||
|
||||
// these objects return a new copy which the python caller should own.
|
||||
%newobject SDObject::Duplicate;
|
||||
%newobject SDChunk::Duplicate;
|
||||
|
||||
Reference in New Issue
Block a user