Class: RailsErrorDashboard::Services::SourceCodeReader
- Inherits:
-
Object
- Object
- RailsErrorDashboard::Services::SourceCodeReader
- Defined in:
- lib/rails_error_dashboard/services/source_code_reader.rb
Overview
Reads source code files from disk with security validation and context lines around a target line number
Constant Summary collapse
- MAX_FILE_SIZE =
10 MB
10 * 1024 * 1024
- MAX_CONTEXT_LINES =
50
Instance Attribute Summary collapse
-
#error ⇒ Object
readonly
Returns the value of attribute error.
-
#file_path ⇒ Object
readonly
Returns the value of attribute file_path.
-
#line_number ⇒ Object
readonly
Returns the value of attribute line_number.
Instance Method Summary collapse
-
#file_exists? ⇒ Boolean
Check if file exists on disk.
-
#initialize(file_path, line_number) ⇒ SourceCodeReader
constructor
Initialize a new source code reader.
-
#read_lines(context: 5) ⇒ Array<Hash>?
Read source code lines with context around the target line.
Constructor Details
#initialize(file_path, line_number) ⇒ SourceCodeReader
Initialize a new source code reader
22 23 24 25 26 |
# File 'lib/rails_error_dashboard/services/source_code_reader.rb', line 22 def initialize(file_path, line_number) @file_path = file_path @line_number = line_number.to_i @error = nil end |
Instance Attribute Details
#error ⇒ Object (readonly)
Returns the value of attribute error.
16 17 18 |
# File 'lib/rails_error_dashboard/services/source_code_reader.rb', line 16 def error @error end |
#file_path ⇒ Object (readonly)
Returns the value of attribute file_path.
16 17 18 |
# File 'lib/rails_error_dashboard/services/source_code_reader.rb', line 16 def file_path @file_path end |
#line_number ⇒ Object (readonly)
Returns the value of attribute line_number.
16 17 18 |
# File 'lib/rails_error_dashboard/services/source_code_reader.rb', line 16 def line_number @line_number end |
Instance Method Details
#file_exists? ⇒ Boolean
Check if file exists on disk
75 76 77 78 79 80 81 82 |
# File 'lib/rails_error_dashboard/services/source_code_reader.rb', line 75 def file_exists? absolute_path = resolve_absolute_path return false unless absolute_path File.exist?(absolute_path) && File.readable?(absolute_path) rescue StandardError false end |
#read_lines(context: 5) ⇒ Array<Hash>?
Read source code lines with context around the target line
32 33 34 35 36 37 38 39 40 41 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 70 |
# File 'lib/rails_error_dashboard/services/source_code_reader.rb', line 32 def read_lines(context: 5) context = [ [ context, MAX_CONTEXT_LINES ].min, 1 ].max # Validate and resolve path absolute_path = resolve_absolute_path return nil unless absolute_path # Validate path is safe unless validate_path!(absolute_path) @error = "Invalid or unsafe file path" return nil end # Check file exists and is readable unless File.exist?(absolute_path) && File.readable?(absolute_path) @error = "File not found or not readable" return nil end # Check file size file_size = File.size(absolute_path) if file_size > MAX_FILE_SIZE @error = "File too large (#{file_size} bytes, max #{MAX_FILE_SIZE})" return nil end # Check if file is binary if binary_file?(absolute_path) @error = "Binary file cannot be displayed" return nil end # Read the specific lines read_specific_lines(absolute_path, line_number - context, line_number + context) rescue StandardError => e @error = "Error reading file: #{e.}" RailsErrorDashboard::Logger.error("SourceCodeReader error for #{file_path}:#{line_number} - #{e.}") nil end |