Exception: Coradoc::ParseError

Inherits:
Error
  • Object
show all
Defined in:
lib/coradoc/errors.rb

Overview

Enhanced error classes with source context support

These error classes provide additional context such as line numbers, column positions, source snippets, and suggestions to help users debug issues.

Examples:

Raising a parse error with context

raise ParseError.new(
  "Unexpected token",
  source: content,
  line: 10,
  column: 5
)

Handling errors with context

begin
  Coradoc.parse(text, format: :markdown)
rescue Coradoc::ParseError => e
  puts e.message_with_context
  puts e.suggestion if e.suggestion
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message, source: nil, line: nil, column: nil, snippet_lines: 3, suggestion: nil) ⇒ ParseError

Create a new parse error with optional source context

Parameters:

  • message (String)

    The error message

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

    The source text being parsed

  • line (Integer, nil) (defaults to: nil)

    The line number (1-indexed)

  • column (Integer, nil) (defaults to: nil)

    The column number (1-indexed)

  • snippet_lines (Integer) (defaults to: 3)

    Number of context lines to show (default: 3)

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

    Optional suggestion for fixing the error



96
97
98
99
100
101
102
103
104
# File 'lib/coradoc/errors.rb', line 96

def initialize(message, source: nil, line: nil, column: nil, snippet_lines: 3,
               suggestion: nil)
  @source = source
  @line = line
  @column = column
  @snippet_lines = snippet_lines
  @suggestion = suggestion || find_suggestion(message, source, line)
  super(build_message(message))
end

Instance Attribute Details

#columnObject (readonly)

Returns the value of attribute column.



86
87
88
# File 'lib/coradoc/errors.rb', line 86

def column
  @column
end

#lineObject (readonly)

Returns the value of attribute line.



86
87
88
# File 'lib/coradoc/errors.rb', line 86

def line
  @line
end

#snippet_linesObject (readonly)

Returns the value of attribute snippet_lines.



86
87
88
# File 'lib/coradoc/errors.rb', line 86

def snippet_lines
  @snippet_lines
end

#sourceObject (readonly)

Returns the value of attribute source.



86
87
88
# File 'lib/coradoc/errors.rb', line 86

def source
  @source
end

#suggestionObject (readonly)

Returns the value of attribute suggestion.



86
87
88
# File 'lib/coradoc/errors.rb', line 86

def suggestion
  @suggestion
end

Instance Method Details

#all_suggestionsArray<String>

Returns all suggestions that match this error

Returns:

  • (Array<String>)

    List of applicable suggestions



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/coradoc/errors.rb', line 151

def all_suggestions
  return [] unless message || source

  suggestions = []
  ERROR_SUGGESTIONS.each do |entry|
    suggestions << format_suggestion(entry) if entry[:pattern].match?(message)
  end

  # Also check source line if available
  if source && line
    source_line = source.lines[line - 1]
    if source_line
      ERROR_SUGGESTIONS.each do |entry|
        suggestions << format_suggestion(entry) if entry[:pattern].match?(source_line)
      end
    end
  end

  suggestions.uniq
end

#message_with_contextString

Returns the error message with full context

Returns:

  • (String)

    Formatted error message with source snippet



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/coradoc/errors.rb', line 109

def message_with_context
  return message unless source && line

  msg = message
  msg += "\n\n"
  msg += source_snippet
  if suggestion
    msg += "\n\n"
    msg += "Suggestion: #{suggestion}"
  end
  msg
end

#source_snippetString

Returns the source snippet around the error location

Returns:

  • (String)

    Formatted source snippet with line numbers



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/coradoc/errors.rb', line 125

def source_snippet
  return '' unless source && line

  lines = source.lines
  start_line = [1, line - snippet_lines].max
  end_line = [lines.length, line + snippet_lines].min

  snippet = []
  (start_line..end_line).each do |i|
    prefix = i == line ? '>>> ' : '    '
    snippet_line = lines[i - 1]&.chomp || ''
    snippet << "#{prefix}#{i.to_s.rjust(4)}: #{snippet_line}"

    # Add column indicator on the error line
    if i == line && column
      indicator = "#{' ' * (prefix.length + 6 + column - 1)}^"
      snippet << indicator
    end
  end

  snippet.join("\n")
end