Improve error handling

Export the timeout kill error and use error instead of string in result
struct.
This commit is contained in:
kortschak 2014-08-02 22:14:24 +09:30
parent fe9ca5ffcc
commit 8ccf842518
4 changed files with 18 additions and 23 deletions

View file

@ -333,7 +333,7 @@ func TestQueries(t *testing.T) {
if j == nil && err == nil { if j == nil && err == nil {
continue continue
} }
if err != nil && err.Error() == "Query Timeout" { if err == gremlin.ErrKillTimeout {
timedOut = true timedOut = true
continue continue
} }

View file

@ -84,7 +84,7 @@ func setupGremlin(env *otto.Otto, ses *Session) {
graph.Set("Emit", func(call otto.FunctionCall) otto.Value { graph.Set("Emit", func(call otto.FunctionCall) otto.Value {
value := call.Argument(0) value := call.Argument(0)
if value.IsDefined() { if value.IsDefined() {
ses.SendResult(&GremlinResult{metaresult: false, err: "", val: &value, actualResults: nil}) ses.SendResult(&GremlinResult{metaresult: false, err: nil, val: &value, actualResults: nil})
} }
return otto.NullValue() return otto.NullValue()
}) })

View file

@ -267,7 +267,7 @@ func runIteratorOnSession(it graph.Iterator, ses *Session) {
} }
tags := make(map[string]graph.Value) tags := make(map[string]graph.Value)
it.TagResults(tags) it.TagResults(tags)
cont := ses.SendResult(&GremlinResult{metaresult: false, err: "", val: nil, actualResults: &tags}) cont := ses.SendResult(&GremlinResult{metaresult: false, err: nil, val: nil, actualResults: &tags})
if !cont { if !cont {
break break
} }
@ -279,7 +279,7 @@ func runIteratorOnSession(it graph.Iterator, ses *Session) {
} }
tags := make(map[string]graph.Value) tags := make(map[string]graph.Value)
it.TagResults(tags) it.TagResults(tags)
cont := ses.SendResult(&GremlinResult{metaresult: false, err: "", val: nil, actualResults: &tags}) cont := ses.SendResult(&GremlinResult{metaresult: false, err: nil, val: nil, actualResults: &tags})
if !cont { if !cont {
break break
} }

View file

@ -66,7 +66,7 @@ func NewSession(inputTripleStore graph.TripleStore, timeoutSec int, persist bool
type GremlinResult struct { type GremlinResult struct {
metaresult bool metaresult bool
err string err error
val *otto.Value val *otto.Value
actualResults *map[string]graph.Value actualResults *map[string]graph.Value
} }
@ -114,17 +114,17 @@ func (s *Session) SendResult(result *GremlinResult) bool {
return false return false
} }
var halt = errors.New("Query Timeout") var ErrKillTimeout = errors.New("query timed out")
func (s *Session) runUnsafe(input interface{}) (otto.Value, error) { func (s *Session) runUnsafe(input interface{}) (otto.Value, error) {
s.kill = make(chan struct{}) s.kill = make(chan struct{})
defer func() { defer func() {
if caught := recover(); caught != nil { if r := recover(); r != nil {
if caught == halt { if r == ErrKillTimeout {
s.err = halt s.err = ErrKillTimeout
return return
} }
panic(caught) // Something else happened, repanic! panic(r)
} }
}() }()
@ -138,7 +138,7 @@ func (s *Session) runUnsafe(input interface{}) (otto.Value, error) {
defer s.envLock.Unlock() defer s.envLock.Unlock()
if s.env != nil { if s.env != nil {
s.env.Interrupt <- func() { s.env.Interrupt <- func() {
panic(halt) panic(ErrKillTimeout)
} }
s.env = s.emptyEnv s.env = s.emptyEnv
} }
@ -161,16 +161,11 @@ func (s *Session) ExecInput(input string, out chan interface{}, limit int) {
} else { } else {
value, err = s.runUnsafe(s.script) value, err = s.runUnsafe(s.script)
} }
if err != nil { out <- &GremlinResult{
out <- &GremlinResult{metaresult: true, metaresult: true,
err: err.Error(), err: err,
val: &value, val: &value,
actualResults: nil} actualResults: nil,
} else {
out <- &GremlinResult{metaresult: true,
err: "",
val: &value,
actualResults: nil}
} }
s.currentChannel = nil s.currentChannel = nil
s.script = nil s.script = nil
@ -183,7 +178,7 @@ func (s *Session) ExecInput(input string, out chan interface{}, limit int) {
func (s *Session) ToText(result interface{}) string { func (s *Session) ToText(result interface{}) string {
data := result.(*GremlinResult) data := result.(*GremlinResult)
if data.metaresult { if data.metaresult {
if data.err != "" { if data.err != nil {
return fmt.Sprintln("Error: ", data.err) return fmt.Sprintln("Error: ", data.err)
} }
if data.val != nil { if data.val != nil {
@ -268,7 +263,7 @@ func (ses *Session) GetJson() ([]interface{}, error) {
} }
select { select {
case <-ses.kill: case <-ses.kill:
return nil, halt return nil, ErrKillTimeout
default: default:
return ses.dataOutput, nil return ses.dataOutput, nil
} }