-/*
- * mono-error.c: Error handling code
+/**
+ * \file
+ * Error handling code
*
* Authors:
* Rodrigo Kumpera (rkumpera@novell.com)
/**
* mono_error_init:
- * @error: Pointer to MonoError struct to initialize
- *
- * Any function which takes a MonoError for purposes of reporting an error
- * is required to call either this or mono_error_init_flags on entry.
+ * \param error Pointer to \c MonoError struct to initialize
+ * Any function which takes a \c MonoError for purposes of reporting an error
+ * is required to call either this or \c mono_error_init_flags on entry.
*/
void
mono_error_init (MonoError *error)
return error->error_code;
}
+const char*
+mono_error_get_exception_name (MonoError *oerror)
+{
+ MonoErrorInternal *error = (MonoErrorInternal*)oerror;
+
+ if (error->error_code == MONO_ERROR_NONE)
+ return NULL;
+
+ return error->exception_name;
+}
+
/*Return a pointer to the internal error message, might be NULL.
Caller should not release it.*/
const char*
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.");
+ mono_error_set_assembly_load (oerror, assembly_name, "Could not load file or assembly '%s' or one of its dependencies.", assembly_name);
}
void
va_end (args);
}
+/**
+ * mono_error_set_file_not_found:
+ *
+ * System.IO.FileNotFoundException
+ */
+void
+mono_error_set_file_not_found (MonoError *oerror, const char *msg_format, ...)
+{
+ va_list args;
+ va_start (args, msg_format);
+ mono_error_set_generic_errorv (oerror, "System.IO", "FileNotFoundException", msg_format, args);
+ va_end (args);
+}
+
void
mono_error_set_invalid_program (MonoError *oerror, const char *msg_format, ...)
{
set_error_message ();
}
+/**
+ * mono_error_set_invalid_cast:
+ *
+ * System.InvalidCastException
+ */
+void
+mono_error_set_invalid_cast (MonoError *oerror)
+{
+ mono_error_set_generic_error (oerror, "System", "InvalidCastException", "");
+}
+
void
mono_error_set_exception_instance (MonoError *oerror, MonoException *exc)
{
error->exn.instance_handle = mono_gchandle_new (exc ? &exc->object : NULL, FALSE);
}
+void
+mono_error_set_exception_handle (MonoError *oerror, MonoExceptionHandle exc)
+{
+ MonoErrorInternal *error = (MonoErrorInternal*)oerror;
+
+ mono_error_prepare (error);
+ error->error_code = MONO_ERROR_EXCEPTION_INSTANCE;
+ error->exn.instance_handle = mono_gchandle_from_handle (MONO_HANDLE_CAST(MonoObject, exc), FALSE);
+}
+
void
mono_error_set_out_of_memory (MonoError *oerror, const char *msg_format, ...)
{
}
+/* Used by mono_error_prepare_exception - it sets its own error on mono_string_new_checked failure. */
+static MonoString*
+string_new_cleanup (MonoDomain *domain, const char *text)
+{
+ MonoError ignored_err;
+ MonoString *result = mono_string_new_checked (domain, text, &ignored_err);
+ mono_error_cleanup (&ignored_err);
+ return result;
+}
+
static MonoString*
get_type_name_as_mono_string (MonoErrorInternal *error, MonoDomain *domain, MonoError *error_out)
{
MonoString* res = NULL;
if (error->type_name) {
- res = mono_string_new (domain, error->type_name);
+ res = string_new_cleanup (domain, error->type_name);
} else {
MonoClass *klass = get_class (error);
if (klass) {
char *name = mono_type_full_name (&klass->byval_arg);
if (name) {
- res = mono_string_new (domain, name);
+ res = string_new_cleanup (domain, name);
g_free (name);
}
}
static void
set_message_on_exception (MonoException *exception, MonoErrorInternal *error, MonoError *error_out)
{
- MonoString *msg = mono_string_new (mono_domain_get (), error->full_message);
+ MonoString *msg = string_new_cleanup (mono_domain_get (), error->full_message);
if (msg)
MONO_OBJECT_SETREF (exception, message, msg);
else
MonoString *assembly_name = NULL, *type_name = NULL, *method_name = NULL, *field_name = NULL, *msg = NULL;
MonoDomain *domain = mono_domain_get ();
- mono_error_init (error_out);
+ error_init (error_out);
switch (error->error_code) {
case MONO_ERROR_NONE:
if (!mono_error_ok (error_out))
break;
- method_name = mono_string_new (domain, error->member_name);
+ method_name = string_new_cleanup (domain, error->member_name);
if (!method_name) {
mono_error_set_out_of_memory (error_out, "Could not allocate method name");
break;
if (!mono_error_ok (error_out))
break;
- field_name = mono_string_new (domain, error->member_name);
+ field_name = string_new_cleanup (domain, error->member_name);
if (!field_name) {
mono_error_set_out_of_memory (error_out, "Could not allocate field name");
break;
break;
if (error->assembly_name) {
- assembly_name = mono_string_new (domain, error->assembly_name);
+ assembly_name = string_new_cleanup (domain, error->assembly_name);
if (!assembly_name) {
mono_error_set_out_of_memory (error_out, "Could not allocate assembly name");
break;
}
+ } else {
+ assembly_name = mono_string_empty (domain);
}
exception = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", "TypeLoadException", type_name, assembly_name, error_out);
case MONO_ERROR_FILE_NOT_FOUND:
case MONO_ERROR_BAD_IMAGE:
if (error->assembly_name) {
- msg = mono_string_new (domain, error->full_message);
+ msg = string_new_cleanup (domain, error->full_message);
if (!msg) {
mono_error_set_out_of_memory (error_out, "Could not allocate message");
break;
}
if (error->assembly_name) {
- assembly_name = mono_string_new (domain, error->assembly_name);
+ assembly_name = string_new_cleanup (domain, error->assembly_name);
if (!assembly_name) {
mono_error_set_out_of_memory (error_out, "Could not allocate assembly name");
break;
mono_error_move (MonoError *dest, MonoError *src)
{
memcpy (dest, src, sizeof (MonoErrorInternal));
- mono_error_init (src);
+ error_init (src);
}
/**
* mono_error_box:
- * @ierror: The input error that will be boxed.
- * @image: The mempool of this image will hold the boxed error.
- *
- * Creates a new boxed error in the given mempool from MonoError.
- * It does not alter ierror, so you still have to clean it up with
- * mono_error_cleanup or mono_error_convert_to_exception or another such function.
- *
- * Returns the boxed error, or NULL if the mempool could not allocate.
+ * \param ierror The input error that will be boxed.
+ * \param image The mempool of this image will hold the boxed error.
+ * Creates a new boxed error in the given mempool from \c MonoError.
+ * It does not alter \p ierror, so you still have to clean it up with
+ * \c mono_error_cleanup or \c mono_error_convert_to_exception or another such function.
+ * \returns the boxed error, or NULL if the mempool could not allocate.
*/
MonoErrorBoxed*
mono_error_box (const MonoError *ierror, MonoImage *image)
/**
* mono_error_set_from_boxed:
- * @oerror: The error that will be set to the contents of the box.
- * @box: A mempool-allocated error.
- *
+ * \param oerror The error that will be set to the contents of the box.
+ * \param box A mempool-allocated error.
* Sets the error condition in the oerror from the contents of the
* given boxed error. Does not alter the boxed error, so it can be
- * used in a future call to mono_error_set_from_boxed as needed. The
- * oerror should've been previously initialized with mono_error_init,
+ * used in a future call to \c mono_error_set_from_boxed as needed. The
+ * \p oerror should've been previously initialized with \c mono_error_init,
* as usual.
- *
- * Returns TRUE on success or FALSE on failure.
+ * \returns TRUE on success or FALSE on failure.
*/
gboolean
mono_error_set_from_boxed (MonoError *oerror, const MonoErrorBoxed *box)