?? glib-error-reporting.html
字號:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"><title>Error Reporting</title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2"><link rel="start" href="index.html" title="GLib Reference Manual"><link rel="up" href="glib-core.html" title="GLib Core Application Support"><link rel="prev" href="glib-IO-Channels.html" title="IO Channels"><link rel="next" href="glib-Warnings-and-Assertions.html" title="Message Output and Debugging Functions"><meta name="generator" content="GTK-Doc V1.9 (XML mode)"><link rel="stylesheet" href="style.css" type="text/css"><link rel="chapter" href="glib.html" title="GLib Overview"><link rel="chapter" href="glib-fundamentals.html" title="GLib Fundamentals"><link rel="chapter" href="glib-core.html" title="GLib Core Application Support"><link rel="chapter" href="glib-utilities.html" title="GLib Utilities"><link rel="chapter" href="glib-data-types.html" title="GLib Data Types"><link rel="chapter" href="tools.html" title="GLib Tools"><link rel="index" href="ix01.html" title="Index"><link rel="index" href="ix02.html" title="Index of deprecated symbols"><link rel="index" href="ix03.html" title="Index of new symbols in 2.2"><link rel="index" href="ix04.html" title="Index of new symbols in 2.4"><link rel="index" href="ix05.html" title="Index of new symbols in 2.6"><link rel="index" href="ix06.html" title="Index of new symbols in 2.8"><link rel="index" href="ix07.html" title="Index of new symbols in 2.10"><link rel="index" href="ix08.html" title="Index of new symbols in 2.12"><link rel="index" href="ix09.html" title="Index of new symbols in 2.14"><link rel="index" href="ix10.html" title="Index of new symbols in 2.16"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2"><tr valign="middle"><td><a accesskey="p" href="glib-IO-Channels.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td><td><a accesskey="u" href="glib-core.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td><td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td><th width="100%" align="center">GLib Reference Manual</th><td><a accesskey="n" href="glib-Warnings-and-Assertions.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td></tr><tr><td colspan="5" class="shortcuts"><nobr><a href="#id2946927" class="shortcut">Top</a>  |  <a href="#id2947282" class="shortcut">Description</a></nobr></td></tr></table><div class="refentry" lang="en"><a name="glib-Error-Reporting"></a><div class="titlepage"></div><div class="refnamediv"><table width="100%"><tr><td valign="top"><h2><a name="id2946927"></a><span class="refentrytitle">Error Reporting</span></h2><p>Error Reporting — a system for reporting errors</p></td><td valign="top" align="right"></td></tr></table></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">#include <glib.h> <a class="link" href="glib-Error-Reporting.html#GError">GError</a>;<a class="link" href="glib-Error-Reporting.html#GError">GError</a>* <a class="link" href="glib-Error-Reporting.html#g-error-new">g_error_new</a> (<a class="link" href="glib-Quarks.html#GQuark">GQuark</a> domain, <a class="link" href="glib-Basic-Types.html#gint">gint</a> code, const <a class="link" href="glib-Basic-Types.html#gchar">gchar</a> *format, ...);<a class="link" href="glib-Error-Reporting.html#GError">GError</a>* <a class="link" href="glib-Error-Reporting.html#g-error-new-literal">g_error_new_literal</a> (<a class="link" href="glib-Quarks.html#GQuark">GQuark</a> domain, <a class="link" href="glib-Basic-Types.html#gint">gint</a> code, const <a class="link" href="glib-Basic-Types.html#gchar">gchar</a> *message);void <a class="link" href="glib-Error-Reporting.html#g-error-free">g_error_free</a> (<a class="link" href="glib-Error-Reporting.html#GError">GError</a> *error);<a class="link" href="glib-Error-Reporting.html#GError">GError</a>* <a class="link" href="glib-Error-Reporting.html#g-error-copy">g_error_copy</a> (const <a class="link" href="glib-Error-Reporting.html#GError">GError</a> *error);<a class="link" href="glib-Basic-Types.html#gboolean">gboolean</a> <a class="link" href="glib-Error-Reporting.html#g-error-matches">g_error_matches</a> (const <a class="link" href="glib-Error-Reporting.html#GError">GError</a> *error, <a class="link" href="glib-Quarks.html#GQuark">GQuark</a> domain, <a class="link" href="glib-Basic-Types.html#gint">gint</a> code);void <a class="link" href="glib-Error-Reporting.html#g-set-error">g_set_error</a> (<a class="link" href="glib-Error-Reporting.html#GError">GError</a> **err, <a class="link" href="glib-Quarks.html#GQuark">GQuark</a> domain, <a class="link" href="glib-Basic-Types.html#gint">gint</a> code, const <a class="link" href="glib-Basic-Types.html#gchar">gchar</a> *format, ...);void <a class="link" href="glib-Error-Reporting.html#g-propagate-error">g_propagate_error</a> (<a class="link" href="glib-Error-Reporting.html#GError">GError</a> **dest, <a class="link" href="glib-Error-Reporting.html#GError">GError</a> *src);void <a class="link" href="glib-Error-Reporting.html#g-clear-error">g_clear_error</a> (<a class="link" href="glib-Error-Reporting.html#GError">GError</a> **err);void <a class="link" href="glib-Error-Reporting.html#g-prefix-error">g_prefix_error</a> (<a class="link" href="glib-Error-Reporting.html#GError">GError</a> **err, const <a class="link" href="glib-Basic-Types.html#gchar">gchar</a> *format, ...);void <a class="link" href="glib-Error-Reporting.html#g-propagate-prefixed-error">g_propagate_prefixed_error</a> (<a class="link" href="glib-Error-Reporting.html#GError">GError</a> **dest, <a class="link" href="glib-Error-Reporting.html#GError">GError</a> *src, const <a class="link" href="glib-Basic-Types.html#gchar">gchar</a> *format, ...);</pre></div><div class="refsect1" lang="en"><a name="id2947282"></a><h2>Description</h2><p>GLib provides a standard method of reporting errors from a called function tothe calling code. (This is the same problem solved by exceptions in otherlanguages.) It's important to understand that this method is both a<span class="emphasis"><em>data type</em></span> (the <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a> object) and a <span class="emphasis"><em>set ofrules.</em></span> If you use <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a> incorrectly, then your code will notproperly interoperate with other code that uses <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a>, and users of your APIwill probably get confused.</p><p>First and foremost: <span class="emphasis"><em><a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a> should only be used to reportrecoverable runtime errors, never to report programming errors.</em></span> Ifthe programmer has screwed up, then you should use <a class="link" href="glib-Message-Logging.html#g-warning"><code class="function">g_warning()</code></a>,<a class="link" href="glib-Warnings-and-Assertions.html#g-return-if-fail"><code class="function">g_return_if_fail()</code></a>, <a class="link" href="glib-Testing.html#g-assert"><code class="function">g_assert()</code></a>, <a class="link" href="glib-Message-Logging.html#g-error"><code class="function">g_error()</code></a>, or some similar facility.(Incidentally, remember that the <a class="link" href="glib-Message-Logging.html#g-error"><code class="function">g_error()</code></a> function should<span class="emphasis"><em>only</em></span> be used for programming errors, it should not be usedto print any error reportable via <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a>.)</p><p>Examples of recoverable runtime errors are "file not found" or "failed to parseinput." Examples of programming errors are "NULL passed to <code class="function">strcmp()</code>" or"attempted to free the same pointer twice." These two kinds of errors arefundamentally different: runtime errors should be handled or reported to theuser, programming errors should be eliminated by fixing the bug in the program.This is why most functions in GLib and GTK+ do not use the <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a> facility.</p><p>Functions that can fail take a return location for a <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a> as their last argument. For example:</p><div class="informalexample"><pre class="programlisting">gboolean g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **error);</pre></div><p>If you pass a non-<a class="link" href="glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> value for the <code class="literal">error</code> argument, it should point to a location where an error can be placed. For example:</p><div class="informalexample"><pre class="programlisting">gchar *contents;GError *err = NULL;g_file_get_contents ("foo.txt", &contents, NULL, &err);g_assert ((contents == NULL && err != NULL) || (contents != NULL && err == NULL));if (err != NULL) { /* Report error to user, and free error */ g_assert (contents == NULL); fprintf (stderr, "Unable to read file: %s\n", err->message); g_error_free (err); } else { /* Use file contents */ g_assert (contents != NULL); }</pre></div><p>Note that <code class="literal">err != NULL</code> in this example is a<span class="emphasis"><em>reliable</em></span> indicator of whether<a class="link" href="glib-File-Utilities.html#g-file-get-contents"><code class="function">g_file_get_contents()</code></a> failed. Additionally, <a class="link" href="glib-File-Utilities.html#g-file-get-contents"><code class="function">g_file_get_contents()</code></a> returnsa boolean which indicates whether it was successful.</p><p>Because <a class="link" href="glib-File-Utilities.html#g-file-get-contents"><code class="function">g_file_get_contents()</code></a> returns <a class="link" href="glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> on failure, if you are onlyinterested in whether it failed and don't need to display an error message, youcan pass <a class="link" href="glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> for the <code class="literal">error</code> argument:</p><div class="informalexample"><pre class="programlisting">if (g_file_get_contents ("foo.txt", &contents, NULL, NULL)) /* ignore errors */ /* no error occurred */ ;else /* error */ ;</pre></div><p></p><p>The <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a> object contains three fields: <code class="literal">domain</code> indicatesthe module the error-reporting function is located in, <code class="literal">code</code>indicates the specific error that occurred, and <code class="literal">message</code> is auser-readable error message with as many details as possible. Several functionsare provided to deal with an error received from a called function:<a class="link" href="glib-Error-Reporting.html#g-error-matches"><code class="function">g_error_matches()</code></a> returns <a class="link" href="glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the error matches a given domain and code,<a class="link" href="glib-Error-Reporting.html#g-propagate-error"><code class="function">g_propagate_error()</code></a> copies an error into an error location (so the callingfunction will receive it), and <a class="link" href="glib-Error-Reporting.html#g-clear-error"><code class="function">g_clear_error()</code></a> clears an error location byfreeing the error and resetting the location to <a class="link" href="glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. To display an error to theuser, simply display <code class="literal">error->message</code>, perhaps along withadditional context known only to the calling function (the file being opened, orwhatever -- though in the <a class="link" href="glib-File-Utilities.html#g-file-get-contents"><code class="function">g_file_get_contents()</code></a> case,<code class="literal">error->message</code> already contains a filename).</p><p>When implementing a function that can report errors, the basic tool is<a class="link" href="glib-Error-Reporting.html#g-set-error"><code class="function">g_set_error()</code></a>. Typically, if a fatal error occurs you want to <a class="link" href="glib-Error-Reporting.html#g-set-error"><code class="function">g_set_error()</code></a>,then return immediately. <a class="link" href="glib-Error-Reporting.html#g-set-error"><code class="function">g_set_error()</code></a> does nothing if the error location passedto it is <a class="link" href="glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. Here's an example:</p><div class="informalexample"><pre class="programlisting">gintfoo_open_file (GError **error){ gint fd; fd = open ("file.txt", O_RDONLY); if (fd < 0) { g_set_error (error, FOO_ERROR, /* error domain */ FOO_ERROR_BLAH, /* error code */ "Failed to open file: %s", /* error message format string */ g_strerror (errno)); return -1; } else return fd;}</pre></div><p></p><p>Things are somewhat more complicated if you yourself call another function thatcan report a <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a>. If the sub-function indicates fatal errors in some wayother than reporting a <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a>, such as by returning <a class="link" href="glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> on success, you cansimply do the following:</p><div class="informalexample"><pre class="programlisting">gbooleanmy_function_that_can_fail (GError **err){ g_return_val_if_fail (err == NULL || *err == NULL, FALSE); if (!sub_function_that_can_fail (err)) { /* assert that error was set by the sub-function */ g_assert (err == NULL || *err != NULL); return FALSE; } /* otherwise continue, no error occurred */ g_assert (err == NULL || *err == NULL);}</pre></div><p></p><p>If the sub-function does not indicate errors other than by reporting a <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a>, you need to create a temporary <a class="link" href="glib-Error-Reporting.html#GError"><span class="type">GError</span></a> since the passed-in one may be <a class="link" href="glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>.<a class="link" href="glib-Error-Reporting.html#g-propagate-error"><code class="function">g_propagate_error()</code></a> is intended for use in this case.</p><div class="informalexample"><pre class="programlisting">gbooleanmy_function_that_can_fail (GError **err){ GError *tmp_error; g_return_val_if_fail (err == NULL || *err == NULL, FALSE); tmp_error = NULL; sub_function_that_can_fail (&tmp_error); if (tmp_error != NULL) { /* store tmp_error in err, if err != NULL, * otherwise call g_error_free() on tmp_error */ g_propagate_error (err, tmp_error); return FALSE; } /* otherwise continue, no error occurred */}</pre></div><p></p><p>Error pileups are always a bug. For example, this code is incorrect:</p><div class="informalexample"><pre class="programlisting">gbooleanmy_function_that_can_fail (GError **err){ GError *tmp_error;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -