#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
#include <stdsoap2.h>
#include <glite/jp/types.h>
}
-int glite_jpis_stack_error_source(glite_jp_context_t ctx, int code, const char *desc, const char *func, int line) {
+int glite_jpis_stack_error_source(glite_jp_context_t ctx, int code, const char *func, int line, const char *descfmt, ...) {
glite_jp_error_t err;
- char *source;
+ char *source, *desc;
+ va_list ap;
+ va_start(ap, descfmt);
+
asprintf(&source, "%s:%d", func, line);
+ if (descfmt) vasprintf(&desc, descfmt, ap);
+ else desc = NULL;
memset(&err, 0, sizeof err);
err.code = code;
err.desc = desc;
err.source = source;
glite_jp_stack_error(ctx, &err);
free(source);
+ free(desc);
+ va_end(ap);
return code;
}
void glite_jpis_trim_soap(struct soap *soap, char **soap_str);
-int glite_jpis_stack_error_source(glite_jp_context_t ctx, int code, const char *desc, const char *func, int line);
+int glite_jpis_stack_error_source(glite_jp_context_t ctx, int code, const char *func, int line, const char *desc, ...);
-#define glite_jpis_stack_error(CTX, CODE, DESC) glite_jpis_stack_error_source((CTX), (CODE), (DESC), __FUNCTION__, __LINE__);
+#define glite_jpis_stack_error(CTX, CODE, DESCFMT...) glite_jpis_stack_error_source((CTX), (CODE), __FUNCTION__, __LINE__, ##DESCFMT);
#endif
if ((done != (status & GLITE_JP_IS_STATE_DONE)) && done) {
ctx->param_state |= done;
if ((ret = glite_jp_db_execute(ctx->update_state_feed_stmt)) != 1) {
- fprintf(stderr, "can't update state of '%s', returned %d records: %s (%s)\n", feedid, ret, jpctx->error->desc, jpctx->error->source);
+ fprintf(stderr, "can't update state of '%s', returned %d records", feedid, ret);
+ if (jpctx->error) fprintf(stderr, ": %s (%s)\n", jpctx->error->desc, jpctx->error->source);
+ else fprintf(stderr, "\n");
goto fail;
}
}
case GLITE_JP_QUERYOP_UNEQUAL:
qop = strdup("!=");
break;
-// FIXME: has index the same metrics?
case GLITE_JP_QUERYOP_GREATER:
qop = strdup(">");
break;
free(qwhere);
free(qa);
- // XXX: add where's for attr origin (not clear now whether stored in separate column
- // or obtained via glite_jp_attrval_from_db...
-
if ((ret = glite_jp_db_execstmt(ctx->jpctx, query, &stmt)) < 0) goto err;
free(query);
free(attr_md5);
free(jobid_md5);
- if ((ret = glite_jp_db_execstmt(ctx->jpctx, query, &stmt)) < 0)
- // unknown attribute
- // XXX: propagate the error to client
- goto err;
+ if ((ret = glite_jp_db_execstmt(ctx->jpctx, query, &stmt)) < 0) {
+ glite_jpis_stack_error(ctx->jpctx, EIO, "SELECT from attribute '%s' failed", attr_name);
+ goto err;
+ }
free(query);
av = *out;
/* test whether there is any indexed attribudes in the condition */
if ( checkIndexedConditions(ctx, in) ) {
glite_jpis_stack_error(ctx->jpctx, EINVAL, "No indexed attribute in query");
- glite_jp_server_err2fault(ctx->jpctx, soap);
- return SOAP_ERR;
+ goto fail;
}
/* test whether there is known attribudes in the condition */
if ( checkConditions(ctx, in) ) {
glite_jpis_stack_error(ctx->jpctx, EINVAL, "Unknown attribute in query");
- glite_jp_server_err2fault(ctx->jpctx, soap);
- return SOAP_ERR;
+ goto fail;
}
/* get all jobids matching the conditions */
if ( get_jobids(ctx, in, &jobids, &ps_list) ) {
- return SOAP_ERR;
+ glite_jpis_stack_error(ctx->jpctx, 0, NULL);
+ goto fail;
}
/* get all requested attributes for matching jobids */
GLITE_SECURITY_GSOAP_LIST_CREATE(soap, out, jobs, struct jptype__jobRecord, size);
for (i=0; (jobids && jobids[i]); i++) {
jr = GLITE_SECURITY_GSOAP_LIST_GET(out->jobs, i);
- if ( get_attrs(soap, ctx, jobids[i], in, jr) ) return SOAP_ERR;
+ if ( get_attrs(soap, ctx, jobids[i], in, jr) ) {
+ glite_jpis_stack_error(ctx->jpctx, 0, NULL);
+ goto fail;
+ }
// XXX: in prototype we return only first value of PS URL
// in future database should contain one more table with URLs
free(ps_list);
return SOAP_OK;
+fail:
+ glite_jp_server_err2fault(ctx->jpctx, soap);
+ return SOAP_ERR;
}
case SOAP_FAULT:
case SOAP_SVR_FAULT:
+ retval = -1;
detail = GLITE_SECURITY_GSOAP_DETAIL(soap);
reason = GLITE_SECURITY_GSOAP_REASON(soap);
dprintf("%s%s\n", prefix, reason);
if (toSyslog) syslog(LOG_ERR, "%s", reason);
+ if (!detail) break;
if (detail->__type != GFNUM && detail->__any) {
// compatibility with clients gSoaps < 2.7.9b
dprintf("%s%s%s\n", prefix, indent, detail->__any);
f = f->reason;
strcat(indent," ");
}
- retval = -1;
break;
default:
ret->code = err->code;
ret->source = soap_strdup(soap,err->source);
ret->text = soap_strdup(soap,strerror(err->code));
- ret->description = soap_strdup(soap,err->desc);
+ ret->description = err->desc ? soap_strdup(soap,err->desc) : NULL;
ret->reason = jp2s_error(soap,err->reason);
}
return ret;
static void glite_jp_server_err2fault(const glite_jp_context_t ctx,struct soap *soap)
{
- struct SOAP_ENV__Detail *detail = soap_malloc(soap,sizeof *detail);
+ struct SOAP_ENV__Detail *detail;
#if GSOAP_VERSION >= 20709
struct jptype__genericFault *f;
f = jp2s_error(soap,ctx->error);
struct _genericFault *f = soap_malloc(soap, sizeof *f);
f->jpelem__genericFault = jp2s_error(soap,ctx->error);
#endif
+ soap_receiver_fault(soap,"Oh, shit!",NULL);
+ // no error in JP context?
+ if (!f) return;
+
+ detail = soap_malloc(soap,sizeof *detail);
memset(detail, 0, sizeof(*detail));
#if GSOAP_VERSION >= 20700
detail->fault = (void *)f;
detail->__type = GFNUM;
detail->__any = NULL;
- soap_receiver_fault(soap,"Oh, shit!",NULL);
if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail;
else soap->fault->detail = detail;
}