Exception: Exception

Defined in:
lib/nitro/compiler/errors.rb

Overview

This supports source code extraction from a full backtrace from any exception and also exposes class methods incase you wish to harness them from elsewhere. – TODO: Cache source code? Memory vs Speed - Is it worth it? FIXME: Don’t change the Exception class, use NitroException or something. ++

Direct Known Subclasses

Nitro::ActionExit, Nitro::RenderExit

Constant Summary collapse

SOURCE_RADIUS =

Radius of the source code to display arround the error line.

5

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.file_and_line_no(step) ⇒ Object

Extracts the filename and line from the given line (step) of the backtrace.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/nitro/compiler/errors.rb', line 24

def file_and_line_no(step)
  file = no = nil
  if res = step.match(/^(.+):(\d+)$/)
    file = res[1]
    no = res[2]
  elsif res = step.match(/^(.+):(\d+):in `.+'$/)
    file = res[1]
    no = res[2]
  end
  if file and no
    [file,no.to_i]
  else
    nil
  end
end

.source_extract(step, indent = 0) ⇒ Object

Extract the source arround the error line.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/nitro/compiler/errors.rb', line 42

def source_extract(step, indent = 0)
  begin
    file, no = file_and_line_no(step)        
    source = File.read(file)

    if file =~ /\.xhtml$/
      source = Compiler.new(Nitro::Controller).transform_template(:action, source)
      no -= 2
    end

    source = source.split("\n")
    start = (no-1) - SOURCE_RADIUS
    finish = (no-1) + SOURCE_RADIUS
    start = 0 if start < 0
    finish = source.size if finish > source.size
  
    number = start
    extract = source[start..finish].collect do |line| 
      number += 1
      line = line.gsub(/; @out #{Nitro::TemplateMixin::START_DELIM}/, ' ?>').gsub(/#{Nitro::TemplateMixin::END_DELIM}/, '<?r ')
      "#{' ' * indent}#{number}: #{line}"
    end  

    return extract.join("\n")
  rescue Object => ex
    ''
  end
end

Instance Method Details

#file_and_line_no(step) ⇒ Object



96
97
98
# File 'lib/nitro/compiler/errors.rb', line 96

def file_and_line_no(step)
  self.class.file_and_line_no(step)
end

#hot_fileObject

Returns the ‘hot’ backtrace file.



92
93
94
# File 'lib/nitro/compiler/errors.rb', line 92

def hot_file
  file_and_line_no(hot_trace_step).first
end

#hot_trace_indexObject

Identifies the ‘hot’ index in the backtrace, where the error actually happened.



76
77
78
79
80
81
82
# File 'lib/nitro/compiler/errors.rb', line 76

def hot_trace_index
  index = 0
  while backtrace[index] =~ /controller\.rb(.*)method_missing/ 
    index += 1
  end
  return index
end

#hot_trace_stepObject

Returns the ‘hot’ backtrace line.



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

def hot_trace_step
  backtrace[hot_trace_index]
end

#source_extract(step = hot_trace_step, indent = 0) ⇒ Object



100
101
102
# File 'lib/nitro/compiler/errors.rb', line 100

def source_extract(step = hot_trace_step, indent = 0)
  self.class.source_extract(step,indent)
end

#source_for_backtrace(indent = 0) ⇒ Object

Extract source for backtrace.



106
107
108
109
110
# File 'lib/nitro/compiler/errors.rb', line 106

def source_for_backtrace(indent = 0)
  backtrace.inject([]) do |sources, step| 
    sources << source_extract(step, indent)
  end
end