From 496732db3a54121d95a083e2f9d265a3fffbfff5 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 17 Apr 2002 18:20:04 +0000 Subject: [PATCH] Automatically generate a failure response if an invocation provider method throws ServiceFailedException. The response for a service request named would be Failed. The response has a single argument which is the reason string provided by the ServiceFailedException. We were doing this by hand all over the place, and now it will be handled automatically. Yay! git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1268 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/server/InvocationManager.java | 35 ++++++++++++++++--- .../presents/server/InvocationProvider.java | 19 +++++++++- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/java/com/threerings/presents/server/InvocationManager.java b/src/java/com/threerings/presents/server/InvocationManager.java index 91d634cd8..478b8e8cf 100644 --- a/src/java/com/threerings/presents/server/InvocationManager.java +++ b/src/java/com/threerings/presents/server/InvocationManager.java @@ -1,14 +1,18 @@ // -// $Id: InvocationManager.java,v 1.10 2001/10/24 00:36:40 mdb Exp $ +// $Id: InvocationManager.java,v 1.11 2002/04/17 18:20:04 mdb Exp $ package com.threerings.presents.server; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; +import com.samskivert.util.StringUtil; + import com.threerings.presents.Log; import com.threerings.presents.dobj.*; -import com.threerings.presents.data.*; +import com.threerings.presents.data.ClientObject; +import com.threerings.presents.data.InvocationObject; import com.threerings.presents.util.ClassUtil; /** @@ -132,14 +136,16 @@ public class InvocationManager // prune the method arguments from the full message arguments Object[] margs = new Object[args.length-1]; int cloid = event.getSourceOid(); - margs[0] = PresentsServer.omgr.getObject(cloid); + ClientObject source = (ClientObject) + PresentsServer.omgr.getObject(cloid); // make sure the client is still around - if (margs[0] == null) { + if (source == null) { Log.warning("Client no longer around for invocation provider " + "request [module=" + module + ", proc=" + procedure + ", cloid=" + cloid + "]."); return; } + margs[0] = source; System.arraycopy(args, 2, margs, 1, args.length-2); // look up the method that will handle this procedure @@ -155,6 +161,23 @@ public class InvocationManager // and invoke it try { procmeth.invoke(provider, margs); + + } catch (InvocationTargetException ite) { + Throwable te = ite.getTargetException(); + if (te instanceof ServiceFailedException) { + // automatically generate a Failed response + provider.sendResponse(source, invid.intValue(), + procedure + FAILED_SUFFIX, + te.getMessage()); + + } else { + Log.warning("Invocation procedure failed " + + "[provider=" + provider + + ", method=" + procmeth + + ", args=" + StringUtil.toString(margs) + "]."); + Log.logStackTrace(te); + } + } catch (Exception e) { Log.warning("Error invoking invocation procedure " + "[provider=" + provider + @@ -167,4 +190,8 @@ public class InvocationManager protected int _invoid; protected HashMap _providers = new HashMap(); protected HashMap _methcache = new HashMap(); + + /** The text that is appended to the procedure name when automatically + * generating a failure response. */ + protected static final String FAILED_SUFFIX = "Failed"; } diff --git a/src/java/com/threerings/presents/server/InvocationProvider.java b/src/java/com/threerings/presents/server/InvocationProvider.java index 4c6cf0cf8..dcbc7e736 100644 --- a/src/java/com/threerings/presents/server/InvocationProvider.java +++ b/src/java/com/threerings/presents/server/InvocationProvider.java @@ -1,5 +1,5 @@ // -// $Id: InvocationProvider.java,v 1.6 2001/10/11 04:07:53 mdb Exp $ +// $Id: InvocationProvider.java,v 1.7 2002/04/17 18:20:04 mdb Exp $ package com.threerings.presents.server; @@ -53,6 +53,23 @@ import com.threerings.presents.dobj.MessageEvent; * the reflection rules for automatic conversion of primitive types * (supply an Integer object for int params, * etc.). + * + *

Note that if an invocation service method throws a {@link + * ServiceFailedException}, the invocation manager will automatically + * issue a response to the client with the string Failed + * appended to the request method. For example, if the client issues a + * request for Foo which results in a call to + * handleFooRequest, which throws a service failed exception, + * the server will automatically issue a failure response named + * FooFailed with the single argument being the + * reason string provided to the constructor of the service + * failed exception. The caller would then implement: + * + *

+ * public void handleFooFailed (int invid, String reason)
+ * 
+ * + * to handle the failure. */ public class InvocationProvider {