Exception: Strling::Core::STRlingParseError

Inherits:
StandardError
  • Object
show all
Defined in:
lib/strling/core/errors.rb

Overview

Rich parse error with position tracking and instructional hints.

This error class transforms parse failures into learning opportunities by providing:

  • The specific error message

  • The exact position where the error occurred

  • The full line of text containing the error

  • A beginner-friendly hint explaining how to fix the issue

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message, pos, text: '', hint: nil) ⇒ STRlingParseError

Initialize a STRlingParseError.

Parameters:

  • message (String)

    A concise description of what went wrong

  • pos (Integer)

    The character position (0-indexed) where the error occurred

  • text (String) (defaults to: '')

    The full input text being parsed (default: “”)

  • hint (String, nil) (defaults to: nil)

    An instructional hint explaining how to fix the error (default: nil)



39
40
41
42
43
44
45
46
47
# File 'lib/strling/core/errors.rb', line 39

def initialize(message, pos, text: '', hint: nil)
  @message = message
  @pos = pos
  @text = text
  @hint = hint

  # Call parent constructor with formatted message
  super(format_error)
end

Instance Attribute Details

#hintString? (readonly)

Returns An instructional hint explaining how to fix the error.

Returns:

  • (String, nil)

    An instructional hint explaining how to fix the error



31
32
33
# File 'lib/strling/core/errors.rb', line 31

def hint
  @hint
end

#messageString (readonly)

Returns A concise description of what went wrong.

Returns:

  • (String)

    A concise description of what went wrong



22
23
24
# File 'lib/strling/core/errors.rb', line 22

def message
  @message
end

#posInteger (readonly)

Returns The character position (0-indexed) where the error occurred.

Returns:

  • (Integer)

    The character position (0-indexed) where the error occurred



25
26
27
# File 'lib/strling/core/errors.rb', line 25

def pos
  @pos
end

#textString (readonly)

Returns The full input text being parsed.

Returns:

  • (String)

    The full input text being parsed



28
29
30
# File 'lib/strling/core/errors.rb', line 28

def text
  @text
end

Instance Method Details

#format_errorString

Format the error in the visionary state format.

Returns:

  • (String)

    A formatted error message with context and hints



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/strling/core/errors.rb', line 52

def format_error
  if text.empty?
    # Fallback to simple format if no text provided
    return "#{message} at position #{pos}"
  end

  # Find the line containing the error
  lines = text.lines(chomp: true)
  current_pos = 0
  line_num = 1
  line_text = ''
  col = pos

  lines.each_with_index do |line, i|
    line_len = line.length + 1 # +1 for newline
    if current_pos + line_len > pos
      line_num = i + 1
      line_text = line
      col = pos - current_pos
      break
    end
    current_pos += line_len
  end

  # Error is beyond the last line
  if line_text.empty?
    if !lines.empty?
      line_num = lines.length
      line_text = lines[-1]
      col = line_text.length
    else
      line_text = text
      col = pos
    end
  end

  # Build the formatted error message
  parts = ["STRling Parse Error: #{message}", '']
  parts << "> #{line_num} | #{line_text}"
  parts << ">   | #{' ' * col}^"

  if hint
    parts << ''
    parts << "Hint: #{hint}"
  end

  parts.join("\n")
end

#to_formatted_stringString

Backwards/JS-friendly alias for getting the formatted error string.

Returns:

  • (String)

    The formatted error message (same as ‘to_s`)



111
112
113
# File 'lib/strling/core/errors.rb', line 111

def to_formatted_string
  format_error
end

#to_lsp_diagnosticHash

Convert the error to LSP Diagnostic format.

Returns a hash compatible with the Language Server Protocol Diagnostic specification, which can be serialized to JSON for communication with LSP clients.

Returns:

  • (Hash)

    A hash containing:

    • range: The line/column range where the error occurred

    • severity: Error severity (1 = Error)

    • message: The error message with hint if available

    • source: “STRling”

    • code: A normalized error code derived from the message



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/strling/core/errors.rb', line 127

def to_lsp_diagnostic
  # Find the line and column containing the error
  lines = text.empty? ? [] : text.lines(chomp: true)
  current_pos = 0
  line_num = 0 # 0-indexed for LSP
  col = pos

  lines.each_with_index do |line, i|
    line_len = line.length + 1 # +1 for newline
    if current_pos + line_len > pos
      line_num = i
      col = pos - current_pos
      break
    end
    current_pos += line_len
  end

  # Error is beyond the last line
  if col == pos && !lines.empty?
    line_num = lines.length - 1
    col = lines[-1].length
  end

  # Build the diagnostic message
  diagnostic_message = message
  diagnostic_message += "\n\nHint: #{hint}" if hint

  # Create error code from message (normalize to snake_case)
  error_code = message.downcase
  [' ', "'", '"', '(', ')', '[', ']', '{', '}', '\\', '/'].each do |char|
    error_code = error_code.gsub(char, '_')
  end
  error_code = error_code.split('_').reject(&:empty?).join('_')

  {
    range: {
      start: { line: line_num, character: col },
      end: { line: line_num, character: col + 1 }
    },
    severity: 1, # 1 = Error, 2 = Warning, 3 = Information, 4 = Hint
    message: diagnostic_message,
    source: 'STRling',
    code: error_code
  }
end

#to_sString

Return the formatted error message.

Returns:

  • (String)

    The formatted error message



104
105
106
# File 'lib/strling/core/errors.rb', line 104

def to_s
  format_error
end