From a47a56d84141c20871f8083f80615a117e459f16 Mon Sep 17 00:00:00 2001 From: Andrei Mihu Date: Fri, 29 Sep 2017 15:34:09 +0100 Subject: [PATCH] Better error responses from runtime RPC or HTTP hooks --- CHANGELOG.md | 1 + server/pipeline_runtime.go | 20 +++++++++++++++++--- server/session_auth.go | 17 ++++++++++++++++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58098f874..fec56804d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [keep a changelog](http://keepachangelog.com/) and this p - Increase default maximum length of various name, location, timezone, and other free text fields to 255 characters. - Increase default maximum length of storage bucket, collection, and record from 70 to 128 characters. - Increase default maximum length of topic room names from 64 to 128 characters. +- Better error responses when runtime function RPC or HTTP hooks fail or return errors. ### Fixed - Realtime notification routing now correctly resolves connected users. diff --git a/server/pipeline_runtime.go b/server/pipeline_runtime.go index c8ad438ed..ca58f4a56 100644 --- a/server/pipeline_runtime.go +++ b/server/pipeline_runtime.go @@ -15,9 +15,9 @@ package server import ( - "fmt" - + "github.com/yuin/gopher-lua" "go.uber.org/zap" + "strings" ) func (p *pipeline) rpc(logger *zap.Logger, session *session, envelope *Envelope) { @@ -36,7 +36,21 @@ func (p *pipeline) rpc(logger *zap.Logger, session *session, envelope *Envelope) result, fnErr := p.runtime.InvokeFunctionRPC(lf, session.userID, session.handle.Load(), session.expiry, rpcMessage.Payload) if fnErr != nil { logger.Error("Runtime RPC function caused an error", zap.String("id", rpcMessage.Id), zap.Error(fnErr)) - session.Send(ErrorMessage(envelope.CollationId, RUNTIME_FUNCTION_EXCEPTION, fmt.Sprintf("Runtime function caused an error: %s", fnErr.Error()))) + if apiErr, ok := fnErr.(*lua.ApiError); ok { + msg := apiErr.Object.String() + if strings.HasPrefix(msg, lf.Proto.SourceName) { + msg = msg[len(lf.Proto.SourceName):] + msgParts := strings.SplitN(msg, ": ", 2) + if len(msgParts) == 2 { + msg = msgParts[1] + } else { + msg = msgParts[0] + } + } + session.Send(ErrorMessage(envelope.CollationId, RUNTIME_FUNCTION_EXCEPTION, msg)) + } else { + session.Send(ErrorMessage(envelope.CollationId, RUNTIME_FUNCTION_EXCEPTION, fnErr.Error())) + } return } diff --git a/server/session_auth.go b/server/session_auth.go index 213f5f5c8..f65bb5805 100644 --- a/server/session_auth.go +++ b/server/session_auth.go @@ -38,6 +38,7 @@ import ( "github.com/gorilla/mux" "github.com/gorilla/websocket" "github.com/satori/go.uuid" + "github.com/yuin/gopher-lua" "go.uber.org/zap" "golang.org/x/crypto/bcrypt" "nakama/pkg/httputil" @@ -230,7 +231,21 @@ func (a *authenticationService) configure() { responseData, funError := a.runtime.InvokeFunctionHTTP(fn, uuid.Nil, "", 0, payload) if funError != nil { a.logger.Error("Runtime function caused an error", zap.String("path", path), zap.Error(funError)) - http.Error(w, fmt.Sprintf("Runtime function caused an error: %s", funError.Error()), 500) + if apiErr, ok := funError.(*lua.ApiError); ok { + msg := apiErr.Object.String() + if strings.HasPrefix(msg, fn.Proto.SourceName) { + msg = msg[len(fn.Proto.SourceName):] + msgParts := strings.SplitN(msg, ": ", 2) + if len(msgParts) == 2 { + msg = msgParts[1] + } else { + msg = msgParts[0] + } + } + http.Error(w, msg, 500) + } else { + http.Error(w, funError.Error(), 500) + } return } -- GitLab