runtimeerror.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package interpreter
  11. import (
  12. "crypto/sha256"
  13. "encoding/base64"
  14. "errors"
  15. "fmt"
  16. "devt.de/krotik/common/lang/graphql/parser"
  17. "devt.de/krotik/common/stringutil"
  18. )
  19. /*
  20. handleRuntimeError handles any errors which happen at runtime.
  21. */
  22. func (rtp *GraphQLRuntimeProvider) handleRuntimeError(err error, path []string, node *parser.ASTNode) {
  23. if err != nil {
  24. // Depuplicate errors (no point in showing the same error twice)
  25. hasher := sha256.New()
  26. hasher.Write([]byte(err.Error()))
  27. hasher.Write([]byte(fmt.Sprint(path)))
  28. hasher.Write([]byte(fmt.Sprint(node.Token.Lline)))
  29. hasher.Write([]byte(fmt.Sprint(node.Token.Lpos)))
  30. errorHash := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
  31. if stringutil.IndexOf(errorHash, rtp.ErrorKeys) == -1 {
  32. rtp.Errors = append(rtp.Errors,
  33. &RuntimeError{rtp.Name, ErrRuntimeError, err.Error(), node,
  34. node.Token.Lline, node.Token.Lpos, false, rtp})
  35. rtp.ErrorPaths = append(rtp.ErrorPaths, path)
  36. rtp.ErrorKeys = append(rtp.ErrorKeys, errorHash)
  37. }
  38. }
  39. }
  40. /*
  41. newRuntimeError creates a new RuntimeError object.
  42. */
  43. func (rtp *GraphQLRuntimeProvider) newFatalRuntimeError(t error, d string, node *parser.ASTNode) error {
  44. return &RuntimeError{rtp.Name, t, d, node, node.Token.Lline, node.Token.Lpos, true, rtp}
  45. }
  46. /*
  47. RuntimeError is a runtime related error
  48. */
  49. type RuntimeError struct {
  50. Source string // Name of the source which was given to the parser
  51. Type error // Error type (to be used for equal checks)
  52. Detail string // Details of this error
  53. Node *parser.ASTNode // AST Node where the error occurred
  54. Line int // Line of the error
  55. Pos int // Position of the error
  56. IsFatal bool // Is a fatal error which should stop the whole operation
  57. RuntimeProvider *GraphQLRuntimeProvider // Runtime provider which produced this error
  58. }
  59. /*
  60. Error returns a human-readable string representation of this error.
  61. */
  62. func (re *RuntimeError) Error() string {
  63. op := re.RuntimeProvider.QueryType
  64. if op == "" {
  65. op = "operation"
  66. }
  67. fatal := ""
  68. if re.IsFatal {
  69. fatal = "Fatal "
  70. }
  71. ret := fmt.Sprintf("%sGraphQL %s error in %s: %v (%v)", fatal, op,
  72. re.Source, re.Type, re.Detail)
  73. if re.Line != 0 {
  74. ret = fmt.Sprintf("%s (Line:%d Pos:%d)", ret, re.Line, re.Pos)
  75. }
  76. return ret
  77. }
  78. /*
  79. Runtime related error types
  80. */
  81. var (
  82. ErrInvalidConstruct = errors.New("Invalid construct")
  83. ErrAmbiguousDefinition = errors.New("Ambiguous definition")
  84. ErrMissingOperation = errors.New("Missing operation")
  85. ErrRuntimeError = errors.New("Runtime error")
  86. )