Fix nil-pointer panic in wspr.

When MethodSignature is called from Prepare, a nil ctx is passed in.  We
have to check for ctx==nil, and pass nil into verror.Make.

This CL also adds tests for the case when MethodNotFound and
WrongNumberOfArg errors are returned, and cleans up the app_test a bit.

Change-Id: I907223d392012482802bdceb0b182c81e8933849
diff --git a/services/wsprd/app/app_test.go b/services/wsprd/app/app_test.go
index cf8cfb4..738c7cb 100644
--- a/services/wsprd/app/app_test.go
+++ b/services/wsprd/app/app_test.go
@@ -14,6 +14,7 @@
 	"v.io/core/veyron2/vdl"
 	"v.io/core/veyron2/vdl/vdlroot/src/signature"
 	"v.io/core/veyron2/verror2"
+	"v.io/wspr/veyron/services/wsprd/ipc/server"
 	"v.io/wspr/veyron/services/wsprd/lib"
 	"v.io/wspr/veyron/services/wsprd/lib/testwriter"
 
@@ -513,20 +514,23 @@
 	var err2 error
 
 	err = call.Finish(&result, &err2)
-	if (err == nil && test.authError != nil) || (err != nil && test.authError == nil) {
-		t.Errorf("unexpected err: %v, %v", err, test.authError)
+
+	// If err is nil and test.authErr is nil reflect.DeepEqual will return
+	// false because the types are different.  Because of this, we only use
+	// reflect.DeepEqual if one of the values is non-nil.  If both values
+	// are nil, then we consider them equal.
+	if (err != nil || test.authError != nil) && !verror2.Equal(err, test.authError) {
+		t.Errorf("unexpected err: got %#v, expected %#v", err, test.authError)
 	}
 
 	if err != nil {
 		return
 	}
+
 	if !reflect.DeepEqual(result, test.finalResponse) {
 		t.Errorf("unexected final response: got %v, expected %v", result, test.finalResponse)
 	}
 
-	// If err2 is nil and test.err is nil reflect.DeepEqual will return false because the
-	// types are different.  Because of this, we only use reflect.DeepEqual if one of
-	// the values is non-nil.  If both values are nil, then we consider them equal.
 	if (err2 != nil || test.err != nil) && !verror2.Equal(err2, test.err) {
 		t.Errorf("unexpected error: got %#v, expected %#v", err2, test.err)
 	}
@@ -552,15 +556,14 @@
 func TestJSServerWithError(t *testing.T) {
 	err := verror2.Make(verror2.Internal, nil)
 	runJsServerTestCase(t, jsServerTestCase{
-		method:        "Add",
-		inArgs:        []interface{}{int32(1), int32(2)},
-		finalResponse: int32(3),
-		err:           err,
+		method: "Divide",
+		inArgs: []interface{}{int32(1), int32(0)},
+		err:    err,
 	})
 }
 
 func TestJSServerWithAuthorizerAndAuthError(t *testing.T) {
-	err := verror2.Make(verror2.Internal, nil)
+	err := verror2.Make(verror2.NoAccess, nil)
 	runJsServerTestCase(t, jsServerTestCase{
 		method:        "Add",
 		inArgs:        []interface{}{int32(1), int32(2)},
@@ -593,3 +596,22 @@
 		finalResponse: int32(10),
 	})
 }
+
+func TestJSServerWithWrongNumberOfArgs(t *testing.T) {
+	err := verror2.Make(server.ErrWrongNumberOfArgs, nil, "Add", 3, 2)
+	runJsServerTestCase(t, jsServerTestCase{
+		method:    "Add",
+		inArgs:    []interface{}{int32(1), int32(2), int32(3)},
+		authError: err,
+	})
+}
+
+func TestJSServerWithMethodNotFound(t *testing.T) {
+	methodName := "UnknownMethod"
+	err := verror2.Make(server.ErrMethodNotFoundInSignature, nil, methodName)
+	runJsServerTestCase(t, jsServerTestCase{
+		method:    methodName,
+		inArgs:    []interface{}{int32(1), int32(2)},
+		authError: err,
+	})
+}
diff --git a/services/wsprd/ipc/server/invoker.go b/services/wsprd/ipc/server/invoker.go
index 0f871b4..5f92174 100644
--- a/services/wsprd/ipc/server/invoker.go
+++ b/services/wsprd/ipc/server/invoker.go
@@ -1,6 +1,7 @@
 package server
 
 import (
+	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/ipc"
 	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/vdl"
@@ -14,8 +15,8 @@
 
 // Errors.
 var (
-	errWrongNumberOfArgs         = verror.Register(pkgPath+".errWrongNumberOfArgs", verror.NoRetry, "{1:}{2:} Method {3} got {4} args, want {5}{:_}")
-	errMethodNotFoundInSignature = verror.Register(pkgPath+".errMethodNotFoundInSignature", verror.NoRetry, "{1:}{2:} Method {3} not found in signature{:_}")
+	ErrWrongNumberOfArgs         = verror.Register(pkgPath+".ErrWrongNumberOfArgs", verror.NoRetry, "{1:}{2:} Method {3} got {4} args, want {5}{:_}")
+	ErrMethodNotFoundInSignature = verror.Register(pkgPath+".ErrMethodNotFoundInSignature", verror.NoRetry, "{1:}{2:} Method {3} not found in signature{:_}")
 )
 
 // invoker holds a delegate function to call on invoke and a list of methods that
@@ -44,7 +45,7 @@
 		return nil, nil, err
 	}
 	if got, want := numArgs, len(method.InArgs); got != want {
-		return nil, nil, verror.Make(errWrongNumberOfArgs, nil, methodName, got, want)
+		return nil, nil, verror.Make(ErrWrongNumberOfArgs, nil, methodName, got, want)
 	}
 	argptrs := make([]interface{}, len(method.InArgs))
 	for ix, arg := range method.InArgs {
@@ -103,5 +104,11 @@
 	if methodSig, ok := signature.FirstMethod(i.signature, method); ok {
 		return methodSig, nil
 	}
-	return signature.Method{}, verror.Make(errMethodNotFoundInSignature, ctx.Context(), method)
+
+	var innerContext *context.T
+	if ctx != nil {
+		innerContext = ctx.Context()
+	}
+
+	return signature.Method{}, verror.Make(ErrMethodNotFoundInSignature, innerContext, method)
 }