|  | # gRPC Error | 
|  |  | 
|  | ## Background | 
|  |  | 
|  | `grpc_error` is the c-core's opaque representation of an error. It holds a | 
|  | collection of integers, strings, timestamps, and child errors that related to | 
|  | the final error. | 
|  |  | 
|  | always present are: | 
|  |  | 
|  | *   GRPC_ERROR_STR_FILE and GRPC_ERROR_INT_FILE_LINE - the source location where | 
|  | the error was generated | 
|  | *   GRPC_ERROR_STR_DESCRIPTION - a human readable description of the error | 
|  | *   GRPC_ERROR_TIME_CREATED - a timestamp indicating when the error happened | 
|  |  | 
|  | An error can also have children; these are other errors that are believed to | 
|  | have contributed to this one. By accumulating children, we can begin to root | 
|  | cause high level failures from low level failures, without having to derive | 
|  | execution paths from log lines. | 
|  |  | 
|  | grpc_errors are refcounted objects, which means they need strict ownership | 
|  | semantics. An extra ref on an error can cause a memory leak, and a missing ref | 
|  | can cause a crash. | 
|  |  | 
|  | This document serves as a detailed overview of grpc_error's ownership rules. It | 
|  | should help people use the errors, as well as help people debug refcount related | 
|  | errors. | 
|  |  | 
|  | ## Clarification of Ownership | 
|  |  | 
|  | If a particular function is said to "own" an error, that means it has the | 
|  | responsibility of calling unref on the error. A function may have access to an | 
|  | error without ownership of it. | 
|  |  | 
|  | This means the function may use the error, but must not call unref on it, since | 
|  | that will be done elsewhere in the code. A function that does not own an error | 
|  | may explicitly take ownership of it by manually calling GRPC_ERROR_REF. | 
|  |  | 
|  | ## Ownership Rules | 
|  |  | 
|  | There are three rules of error ownership, which we will go over in detail. | 
|  |  | 
|  | *   If `grpc_error` is returned by a function, the caller owns a ref to that | 
|  | instance. | 
|  | *   If a `grpc_error` is passed to a `grpc_closure` callback function, then that | 
|  | function does not own a ref to the error. | 
|  | *   if a `grpc_error` is passed to *any other function*, then that function | 
|  | takes ownership of the error. | 
|  |  | 
|  | ### Rule 1 | 
|  |  | 
|  | > If `grpc_error` is returned by a function, the caller owns a ref to that | 
|  | > instance.* | 
|  |  | 
|  | For example, in the following code block, error1 and error2 are owned by the | 
|  | current function. | 
|  |  | 
|  | ```C | 
|  | grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); | 
|  | grpc_error* error2 = some_operation_that_might_fail(...); | 
|  | ``` | 
|  |  | 
|  | The current function would have to explicitly call GRPC_ERROR_UNREF on the | 
|  | errors, or pass them along to a function that would take over the ownership. | 
|  |  | 
|  | ### Rule 2 | 
|  |  | 
|  | > If a `grpc_error` is passed to a `grpc_closure` callback function, then that | 
|  | > function does not own a ref to the error. | 
|  |  | 
|  | A `grpc_closure` callback function is any function that has the signature: | 
|  |  | 
|  | ```C | 
|  | void (*cb)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); | 
|  | ``` | 
|  |  | 
|  | This means that the error ownership is NOT transferred when a functions calls: | 
|  |  | 
|  | ```C | 
|  | c->cb(exec_ctx, c->cb_arg, err); | 
|  | ``` | 
|  |  | 
|  | The caller is still responsible for unref-ing the error. | 
|  |  | 
|  | However, the above line is currently being phased out! It is safer to invoke | 
|  | callbacks with `GRPC_CLOSURE_RUN` and `GRPC_CLOSURE_SCHED`. These functions are | 
|  | not callbacks, so they will take ownership of the error passed to them. | 
|  |  | 
|  | ```C | 
|  | grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); | 
|  | GRPC_CLOSURE_RUN(exec_ctx, cb, error); | 
|  | // current function no longer has ownership of the error | 
|  | ``` | 
|  |  | 
|  | If you schedule or run a closure, but still need ownership of the error, then | 
|  | you must explicitly take a reference. | 
|  |  | 
|  | ```C | 
|  | grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); | 
|  | GRPC_CLOSURE_RUN(exec_ctx, cb, GRPC_ERROR_REF(error)); | 
|  | // do some other things with the error | 
|  | GRPC_ERROR_UNREF(error); | 
|  | ``` | 
|  |  | 
|  | Rule 2 is more important to keep in mind when **implementing** `grpc_closure` | 
|  | callback functions. You must keep in mind that you do not own the error, and | 
|  | must not unref it. More importantly, you cannot pass it to any function that | 
|  | would take ownership of the error, without explicitly taking ownership yourself. | 
|  | For example: | 
|  |  | 
|  | ```C | 
|  | void on_some_action(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { | 
|  | // this would cause a crash, because some_function will unref the error, | 
|  | // and the caller of this callback will also unref it. | 
|  | some_function(error); | 
|  |  | 
|  | // this callback function must take ownership, so it can give that | 
|  | // ownership to the function it is calling. | 
|  | some_function(GRPC_ERROR_REF(error)); | 
|  | } | 
|  | ``` | 
|  |  | 
|  | ### Rule 3 | 
|  |  | 
|  | > if a `grpc_error` is passed to *any other function*, then that function takes | 
|  | > ownership of the error. | 
|  |  | 
|  | Take the following example: | 
|  |  | 
|  | ```C | 
|  | grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); | 
|  | // do some things | 
|  | some_function(error); | 
|  | // can't use error anymore! might be gone. | 
|  | ``` | 
|  |  | 
|  | When some_function is called, it takes over the ownership of the error, and it | 
|  | will eventually unref it. So the caller can no longer safely use the error. | 
|  |  | 
|  | If the caller needed to keep using the error (or passing it to other functions), | 
|  | if would have to take on a reference to it. This is a common pattern seen. | 
|  |  | 
|  | ```C | 
|  | void func() { | 
|  | grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error"); | 
|  | some_function(GRPC_ERROR_REF(error)); | 
|  | // do things | 
|  | some_other_function(GRPC_ERROR_REF(error)); | 
|  | // do more things | 
|  | some_last_function(error); | 
|  | } | 
|  | ``` | 
|  |  | 
|  | The last call takes ownership and will eventually give the error its final | 
|  | unref. | 
|  |  | 
|  | When **implementing** a function that takes an error (and is not a | 
|  | `grpc_closure` callback function), you must ensure the error is unref-ed either | 
|  | by doing it explicitly with GRPC_ERROR_UNREF, or by passing the error to a | 
|  | function that takes over the ownership. |