#include "mono-error-internals.h"
#include <mono/metadata/exception.h>
-#include <mono/metadata/object-internals.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/debug-helpers.h>
if (error->error_code != MONO_ERROR_NONE)
return;
- error->type_name = error->assembly_name = error->member_name = error->full_message = error->exception_name_space = error->exception_name = NULL;
+ error->type_name = error->assembly_name = error->member_name = error->full_message = error->exception_name_space = error->exception_name = error->full_message_with_fields = NULL;
error->klass = NULL;
error->message [0] = 0;
}
+static const char*
+get_type_name (MonoErrorInternal *error)
+{
+ if (error->type_name)
+ return error->type_name;
+ if (error->klass)
+ return error->klass->name;
+ return "<unknown type>";
+}
+
+static const char*
+get_assembly_name (MonoErrorInternal *error)
+{
+ if (error->assembly_name)
+ return error->assembly_name;
+ if (error->klass && error->klass->image)
+ return error->klass->image->name;
+ return "<unknown assembly>";
+}
+
void
mono_error_init_flags (MonoError *oerror, unsigned short flags)
{
return;
g_free ((char*)error->full_message);
+ g_free ((char*)error->full_message_with_fields);
if (!(error->flags & MONO_ERROR_FREE_STRINGS)) //no memory was allocated
return;
return error->error_code == MONO_ERROR_NONE;
}
+void
+mono_error_assert_ok (MonoError *error)
+{
+ if (mono_error_ok (error))
+ return;
+
+ g_error ("%s\n", mono_error_get_message (error));
+}
+
unsigned short
mono_error_get_error_code (MonoError *error)
{
MonoErrorInternal *error = (MonoErrorInternal*)oerror;
if (error->error_code == MONO_ERROR_NONE)
return NULL;
- return mono_internal_error_get_message (error);
+ if (error->full_message_with_fields)
+ return error->full_message_with_fields;
+
+ error->full_message_with_fields = g_strdup_printf ("%s assembly:%s type:%s member:%s",
+ mono_internal_error_get_message (error),
+ get_assembly_name (error),
+ get_type_name (error),
+ error->member_name ? error->member_name : "<none>");
+
+ return error->full_message_with_fields ? error->full_message_with_fields : mono_internal_error_get_message (error);
}
/*
set_error_message ();
}
+
+void
+mono_error_set_assembly_load_simple (MonoError *oerror, const char *assembly_name, gboolean refection_only)
+{
+ if (refection_only)
+ mono_error_set_assembly_load (oerror, assembly_name, "Cannot resolve dependency to assembly because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.");
+ else
+ mono_error_set_assembly_load (oerror, assembly_name, "Could not load file or assembly or one of its dependencies.");
+}
+
void
mono_error_set_type_load_class (MonoError *oerror, MonoClass *klass, const char *msg_format, ...)
{
set_error_message ();
}
+/*
+ * Different than other functions, this one here assumes that type_name and assembly_name to have been allocated just for us.
+ * Which means mono_error_cleanup will free them.
+ */
void
mono_error_set_type_load_name (MonoError *oerror, const char *type_name, const char *assembly_name, const char *msg_format, ...)
{
error->error_code = MONO_ERROR_TYPE_LOAD;
mono_error_set_type_name (oerror, type_name);
mono_error_set_assembly_name (oerror, assembly_name);
+ mono_error_dup_strings (oerror, FALSE);
set_error_message ();
}
{
MonoLoaderError *loader_error = mono_loader_get_last_error ();
MonoErrorInternal *error = (MonoErrorInternal*)oerror;
+ gboolean dup_strings = TRUE;
mono_error_prepare (error);
-
if (!loader_error) {
mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Runtime tried to produce a mono-error from an empty loader-error");
return;
case MONO_EXCEPTION_NONE:
mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Runtime tried to produce a mono-error from a non-error loader-error");
break;
- case MONO_EXCEPTION_SECURITY_LINKDEMAND:
- case MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND:
- mono_error_set_generic_error (oerror, "System.Security", "SecurityException", "Failed for unknown reasons.");
- break;
case MONO_EXCEPTION_INVALID_PROGRAM:
mono_error_set_generic_error (oerror, "System", "InvalidProgramException", "Failed for unknown reasons.");
break;
case MONO_EXCEPTION_TYPE_LOAD:
- mono_error_set_type_load_name (oerror, loader_error->class_name, loader_error->assembly_name, "Failed for unknown reasons.");
+ mono_error_set_type_load_name (oerror, g_strdup (loader_error->class_name), g_strdup (loader_error->assembly_name), "Failed for unknown reasons.");
+ dup_strings = FALSE;
break;
case MONO_EXCEPTION_FILE_NOT_FOUND:
- if (loader_error->ref_only)
- mono_error_set_assembly_load (oerror, loader_error->assembly_name, "Cannot resolve dependency to assembly because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.");
- else
- mono_error_set_assembly_load (oerror, loader_error->assembly_name, "Could not load file or assembly or one of its dependencies.");
+ mono_error_set_assembly_load_simple (oerror, loader_error->assembly_name, loader_error->ref_only);
break;
case MONO_EXCEPTION_METHOD_ACCESS:
break;
}
- mono_error_dup_strings (oerror, TRUE);
+ mono_error_dup_strings (oerror, dup_strings);
mono_loader_clear_error ();
}
-static const char*
-get_type_name (MonoErrorInternal *error)
-{
- if (error->type_name)
- return error->type_name;
- if (error->klass)
- return error->klass->name;
- return "<unknown type>";
-}
-
-static const char*
-get_assembly_name (MonoErrorInternal *error)
-{
- if (error->assembly_name)
- return error->assembly_name;
- if (error->klass && error->klass->image)
- return error->klass->image->name;
- return "<unknown assembly>";
-}
-
void
mono_loader_set_error_from_mono_error (MonoError *oerror)
{
mono_error_prepare (error);
error->error_code = MONO_ERROR_NOT_VERIFIABLE;
- mono_error_set_class (oerror, method->klass);
- if (method)
+ if (method) {
+ mono_error_set_class (oerror, method->klass);
mono_error_set_member_name (oerror, mono_method_full_name (method, 1));
+ }
set_error_message ();
}
}
/*
-Raises the exception of @error.
-Does nothing if @error has a success error code.
-Aborts in case of a double fault. This happens when it can't recover from an error caused by trying
-to construct the first exception object.
-The error object @error is cleaned up.
+Convert this MonoError to an exception if it's faulty or return NULL.
+The error object is cleant after.
*/
-void
-mono_error_raise_exception (MonoError *target_error)
+
+MonoException*
+mono_error_convert_to_exception (MonoError *target_error)
{
MonoError error;
MonoException *ex;
if (mono_error_ok (target_error))
- return;
+ return NULL;
ex = mono_error_prepare_exception (target_error, &error);
if (!mono_error_ok (&error)) {
mono_error_cleanup (&error);
}
mono_error_cleanup (target_error);
-
- mono_raise_exception (ex);
+ return ex;
}