On Mon, Mar 30, 2015 at 11:06 AM, Bruno Albuquerque <[email protected]> wrote:
> Actually i think I was not clear about what I need. How would I apply
> Err_trap for a higher level function? For example, a call to Indexer_new()
> might fail under some circunstances and the program will exit due to that,
> I would like for it not to exit immediately (for example, to be able to do
> something else if the call fails). indexer_new() does nto accept a context
> and it returns something when it works.
>
> Again, i might just be missing something obvious.
FWIW, Indexer_new() is an example of a sub-optimal API that we should change.
The existing approach is a legacy of Lucy's Lucene heritage. In Java the
idiom would be to wrap `new Indexer()` in a `try` block, which works fine and
does not leak memory. What we ought to have instead in Lucy is
Indexer_open(), which returns NULL and sets an error variable on expected
failure cases such as an unsuccessful attempt to acquire the write lock.
By the way, I see you writing to the golang-nuts mailing list and it seems
that you are wrapping the C bindings (presumably from the current 0.4.2 public
release). You may be interested to know that current Git master has some
proof-of-concept Go bindings, which include `lucy.OpenIndexer()` and an
exception mechanism implemented using Go's `panic` -- including a
`clownfish.TrapErr()` function which takes a Go closure rather than a C
function pointer and context.
But to get back to your question, what you would do is adapt Nick's sample
code to wrap Indexer_new().
struct IndexerContext {
Schema *schema;
Obj *index;
IndexManager *manager;
int32_t flags;
Indexer *retval;
};
static void
try_indexer_new(void *vcontext) {
struct IndexerContext *context = (struct IndexerContext*)vcontext;
context->retval = Indexer_new(context->schema, context->index,
context->manager, context->flags);
}
Indexer*
open_indexer(Schema *schema, Obj *index, IndexManager *manager,
int32_t flags) {
struct IndexerContext context;
context.schema = schema;
context.index = index;
context.manager = manager;
context.flags = flags;
context.retval = NULL;
Err *error = Err_trap(try_indexer_new, &context);
if (error != NULL) {
/* Handle error. */
}
return context.retval;
}
The error trapping code in the lucy.OpenIndexer() Go wrapper is similar:
https://git1-us-west.apache.org/repos/asf?p=lucy.git;a=blob;f=go/lucy/index.go;h=f0e09797210253a0e4dde83280f9c49744667aa1;hb=27842415a072d8b8a9f026df1d1f0b2a96b086e3#l76
Marvin Humphrey