From 4d488222cc06d4329916b4c8365cd9ac7c534455 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 13 Jun 2007 08:04:03 +0000 Subject: [PATCH] For errors, pazpar2 returns diagnostic 'code', 'msg' (text representation of code) + additional info for error. This allows clients to handle errors in more proper manner. --- src/http_command.c | 80 ++++++++++++++++++++++++++++++++++++---------------- src/logic.c | 23 ++++++++++----- src/pazpar2.h | 21 ++++++++++++-- 3 files changed, 90 insertions(+), 34 deletions(-) diff --git a/src/http_command.c b/src/http_command.c index b92b437..eaf4785 100644 --- a/src/http_command.c +++ b/src/http_command.c @@ -1,4 +1,4 @@ -/* $Id: http_command.c,v 1.50 2007-06-12 09:26:40 adam Exp $ +/* $Id: http_command.c,v 1.51 2007-06-13 08:04:03 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -20,7 +20,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA */ /* - * $Id: http_command.c,v 1.50 2007-06-12 09:26:40 adam Exp $ + * $Id: http_command.c,v 1.51 2007-06-13 08:04:03 adam Exp $ */ #include @@ -60,7 +60,6 @@ struct http_session { }; static struct http_session *session_list = 0; - void http_session_destroy(struct http_session *s); static void session_timeout(IOCHAN i, int event) @@ -103,22 +102,52 @@ void http_session_destroy(struct http_session *s) nmem_destroy(s->nmem); } +static const char *get_msg(enum pazpar2_error_code code) +{ + struct pazpar2_error_msg { + enum pazpar2_error_code code; + const char *msg; + }; + static const struct pazpar2_error_msg ar[] = { + { PAZPAR2_NO_SESSION, "Session does not exist or it has expired"}, + { PAZPAR2_MISSING_PARAMETER, "Missing parameter"}, + { PAZPAR2_MALFORMED_PARAMETER_VALUE, "Malformed parameter value"}, + { PAZPAR2_MALFORMED_PARAMETER_ENCODING, "Malformed parameter encoding"}, + { PAZPAR2_MALFORMED_SETTING, "Malformed setting argument"}, + { PAZPAR2_HITCOUNTS_FAILED, "Failed to retrieve hitcounts"}, + { PAZPAR2_RECORD_MISSING, "Record missing"}, + { PAZPAR2_NO_TARGETS, "No targets"}, + { PAZPAR2_CONFIG_TARGET, "Target cannot be configured"}, + { 0, 0 } + }; + int i = 0; + while (ar[i].msg) + { + if (code == ar[i].code) + return ar[i].msg; + i++; + } + return "No error"; +} + static void error(struct http_response *rs, - const char *code, const char *msg, const char *extra) + enum pazpar2_error_code code, + const char *addinfo) { struct http_channel *c = rs->channel; char text[1024]; - char *sep = extra ? ": " : ""; + const char *http_status = "417"; + const char *msg = get_msg(code); rs->msg = nmem_strdup(c->nmem, msg); - strcpy(rs->code, code); + strcpy(rs->code, http_status); yaz_snprintf(text, sizeof(text), - "%s%s%s", msg, sep, - extra ? extra : ""); + "%s", (int) code, + msg, addinfo ? addinfo : ""); - yaz_log(YLOG_WARN, "HTTP %s %s%s%s", code, msg, sep, - extra ? extra : ""); + yaz_log(YLOG_WARN, "HTTP %s %s%s%s", http_status, + msg, addinfo ? ": " : "" , addinfo ? addinfo : ""); rs->payload = nmem_strdup(c->nmem, text); http_send_response(c); } @@ -156,7 +185,7 @@ static struct http_session *locate_session(struct http_request *rq, struct http_ if (!session) { - error(rs, "417", "Must supply session", 0); + error(rs, PAZPAR2_MISSING_PARAMETER, "session"); return 0; } id = atoi(session); @@ -166,7 +195,7 @@ static struct http_session *locate_session(struct http_request *rq, struct http_ iochan_activity(p->timeout_iochan); return p; } - error(rs, "417", "Session does not exist, or it has expired", 0); + error(rs, PAZPAR2_NO_SESSION, session); return 0; } @@ -189,7 +218,7 @@ static int process_settings(struct session *se, struct http_request *rq, nmem_strsplit(se->session_nmem, "[]", a->name, &res, &num); if (num != 2) { - error(rs, "417", "Malformed setting argument", a->name); + error(rs, PAZPAR2_MALFORMED_SETTING, a->name); return -1; } setting = res[0]; @@ -373,7 +402,7 @@ static void cmd_bytarget(struct http_channel *c) return; if (!(ht = hitsbytarget(s->psession, &count))) { - error(rs, "500", "Failed to retrieve hitcounts", 0); + error(rs, PAZPAR2_HITCOUNTS_FAILED, 0); return; } wrbuf_rewind(c->wrbuf); @@ -469,14 +498,14 @@ static void cmd_record(struct http_channel *c) return; if (!idstr) { - error(rs, "417", "Must supply id", 0); + error(rs, PAZPAR2_MISSING_PARAMETER, "id"); return; } wrbuf_rewind(c->wrbuf); id = atoi(idstr); if (!(rec = show_single(s->psession, id))) { - error(rs, "500", "Record missing", 0); + error(rs, PAZPAR2_RECORD_MISSING, idstr); return; } wrbuf_puts(c->wrbuf, "\n"); @@ -520,7 +549,7 @@ static void show_records(struct http_channel *c, int active) sort = "relevance"; if (!(sp = reclist_parse_sortparms(c->nmem, sort))) { - error(rs, "500", "Bad sort parameters", 0); + error(rs, PAZPAR2_MALFORMED_PARAMETER_VALUE, "sort"); return; } @@ -632,24 +661,25 @@ static void cmd_search(struct http_channel *c) struct http_session *s = locate_session(rq, rs); char *query = http_argbyname(rq, "query"); char *filter = http_argbyname(rq, "filter"); - char *res; + enum pazpar2_error_code code; + const char *addinfo = 0; if (!s) return; if (!query) { - error(rs, "417", "Must supply query", 0); + error(rs, PAZPAR2_MISSING_PARAMETER, "query"); return; } if (!utf_8_valid(query)) { - error(rs, "417", "Query not UTF-8 encoded", 0); + error(rs, PAZPAR2_MALFORMED_PARAMETER_ENCODING, "query"); return; } - res = search(s->psession, query, filter); - if (res) + code = search(s->psession, query, filter, &addinfo); + if (code) { - error(rs, "417", res, 0); + error(rs, code, addinfo); return; } rs->payload = "OK"; @@ -748,7 +778,7 @@ void http_command(struct http_channel *c) if (!command) { - error(rs, "417", "Must supply command", 0); + error(rs, PAZPAR2_MISSING_PARAMETER, "command"); return; } for (i = 0; commands[i].name; i++) @@ -758,7 +788,7 @@ void http_command(struct http_channel *c) break; } if (!commands[i].name) - error(rs, "417", "Unknown command", command); + error(rs, PAZPAR2_MALFORMED_PARAMETER_VALUE, "command"); return; } diff --git a/src/logic.c b/src/logic.c index c9a0f67..e61d811 100644 --- a/src/logic.c +++ b/src/logic.c @@ -1,4 +1,4 @@ -/* $Id: logic.c,v 1.40 2007-06-11 12:08:23 adam Exp $ +/* $Id: logic.c,v 1.41 2007-06-13 08:04:03 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -468,7 +468,9 @@ static struct database_criterion *parse_filter(NMEM m, const char *buf) return res; } -char *search(struct session *se, char *query, char *filter) +enum pazpar2_error_code search(struct session *se, + char *query, char *filter, + const char **addinfo) { int live_channels = 0; struct client *cl; @@ -476,6 +478,7 @@ char *search(struct session *se, char *query, char *filter) yaz_log(YLOG_DEBUG, "Search"); + *addinfo = 0; nmem_reset(se->nmem); criteria = parse_filter(se->nmem, filter); se->requestid++; @@ -490,23 +493,29 @@ char *search(struct session *se, char *query, char *filter) se->expected_maxrecs = maxrecs; } else - return "NOTARGETS"; + return PAZPAR2_NO_TARGETS; se->relevance = 0; for (cl = se->clients; cl; cl = client_next_in_session(cl)) { if (prepare_session_database(se, client_get_database(cl)) < 0) - return "CONFIG_ERROR"; + { + *addinfo = client_get_database(cl)->database->url; + return PAZPAR2_CONFIG_TARGET; + } // Query must parse for all targets - if (client_parse_query(cl, query) < 0) - return "QUERY"; + if (client_parse_query(cl, query) < 0) + { + *addinfo = "query"; + return PAZPAR2_MALFORMED_PARAMETER_VALUE; + } } for (cl = se->clients; cl; cl = client_next_in_session(cl)) client_prep_connection(cl); - return 0; + return PAZPAR2_NO_ERROR; } // Creates a new session_database object for a database diff --git a/src/pazpar2.h b/src/pazpar2.h index d257874..0e69b2c 100644 --- a/src/pazpar2.h +++ b/src/pazpar2.h @@ -1,4 +1,4 @@ -/* $Id: pazpar2.h,v 1.39 2007-06-12 13:02:38 adam Exp $ +/* $Id: pazpar2.h,v 1.40 2007-06-13 08:04:03 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -43,6 +43,21 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA struct record; struct client; + +enum pazpar2_error_code { + PAZPAR2_NO_ERROR = 0, + + PAZPAR2_NO_SESSION, + PAZPAR2_MISSING_PARAMETER, + PAZPAR2_MALFORMED_PARAMETER_VALUE, + PAZPAR2_MALFORMED_PARAMETER_ENCODING, + PAZPAR2_MALFORMED_SETTING, + PAZPAR2_HITCOUNTS_FAILED, + PAZPAR2_RECORD_MISSING, + PAZPAR2_NO_TARGETS, + PAZPAR2_CONFIG_TARGET +}; + // Represents a (virtual) database on a host struct database { struct host *host; @@ -149,7 +164,8 @@ struct session *new_session(NMEM nmem); void destroy_session(struct session *s); int load_targets(struct session *s, const char *fn); void statistics(struct session *s, struct statistics *stat); -char *search(struct session *s, char *query, char *filter); +enum pazpar2_error_code search(struct session *s, char *query, + char *filter, const char **addinfo); struct record_cluster **show(struct session *s, struct reclist_sortparms *sp, int start, int *num, int *total, int *sumhits, NMEM nmem_show); struct record_cluster *show_single(struct session *s, int id); @@ -179,6 +195,7 @@ int pazpar2_process(int debug, void (*work)(void *data), void *data, const char *pidfile, const char *uid); + #endif /* -- 1.7.10.4