Skip to content

Commit

Permalink
Create error classes for Filesystem errors
Browse files Browse the repository at this point in the history
  • Loading branch information
denisdefreyne committed Dec 20, 2016
1 parent a7293dc commit 3793a07
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 26 deletions.
30 changes: 10 additions & 20 deletions lib/nanoc/data_sources/filesystem.rb
Expand Up @@ -117,7 +117,7 @@ def read_proto_document(content_filename, meta_filename, klass)

ProtoDocument.new(is_binary: true, filename: content_filename, attributes: meta)
elsif is_binary && klass == Nanoc::Int::Layout
raise "The layout file '#{content_filename}' is a binary file, but layouts can only be textual"
raise Errors::BinaryLayout.new(content_filename)
else
parse_result = parse(content_filename, meta_filename)

Expand Down Expand Up @@ -239,11 +239,11 @@ def all_split_files_in(dir_name)

# Check number of files per type
unless [0, 1].include?(meta_filenames.size)
raise "Found #{meta_filenames.size} meta files for #{basename}; expected 0 or 1"
raise Errors::MultipleMetaFiles.new(meta_filenames, basename)
end
unless config[:identifier_type] == 'full'
unless [0, 1].include?(content_filenames.size)
raise "Found #{content_filenames.size} content files for #{basename}; expected 0 or 1"
raise Errors::MultipleContentFiles.new(meta_filenames, basename)
end
end

Expand Down Expand Up @@ -352,7 +352,7 @@ def parse_with_frontmatter(content_filename)

pieces = data.split(/^(-{5}|-{3})[ \t]*\r?\n?/, 3)
if pieces.size < 4
raise "The file '#{content_filename}' appears to start with a metadata section (three or five dashes at the top) but it does not seem to be in the correct format."
raise Errors::InvalidFormat.new(content_filename)
end

meta = parse_metadata(pieces[2], content_filename)
Expand All @@ -366,7 +366,7 @@ def parse_metadata(data, filename)
begin
meta = YAML.load(data) || {}
rescue => e
raise "Could not parse YAML for #{filename}: #{e.message}"
raise Errors::UnparseableMetadata.new(filename, e)
end

verify_meta(meta, filename)
Expand All @@ -386,16 +386,10 @@ def initialize(content:, attributes:, attributes_data:)
end
end

class InvalidMetadataError < Nanoc::Error
def initialize(filename, klass)
super("The file #{filename} has invalid metadata (expected key-value pairs, found #{klass} instead)")
end
end

def verify_meta(meta, filename)
return if meta.is_a?(Hash)

raise InvalidMetadataError.new(filename, meta.class)
raise Errors::InvalidMetadata.new(filename, meta.class)
end

# Reads the content of the file with the given name and returns a string
Expand All @@ -407,7 +401,7 @@ def read(filename)
begin
data = File.read(filename)
rescue => e
raise "Could not read #{filename}: #{e.inspect}"
raise Errors::FileUnreadable.new(filename, e)
end

# Fix
Expand All @@ -422,11 +416,11 @@ def read(filename)
begin
data.encode!('UTF-8')
rescue
raise_encoding_error(filename, original_encoding)
raise Errors::InvalidEncoding.new(filename, original_encoding)
end

unless data.valid_encoding?
raise_encoding_error(filename, original_encoding)
raise Errors::InvalidEncoding.new(filename, original_encoding)
end
end

Expand All @@ -435,12 +429,8 @@ def read(filename)

data
end

# Raises an invalid encoding error for the given filename and encoding.
def raise_encoding_error(filename, encoding)
raise "Could not read #{filename} because the file is not valid #{encoding}."
end
end
end

require_relative 'filesystem/tools'
require_relative 'filesystem/errors'
55 changes: 55 additions & 0 deletions lib/nanoc/data_sources/filesystem/errors.rb
@@ -0,0 +1,55 @@
class Nanoc::DataSources::Filesystem < Nanoc::DataSource
# @api private
module Errors
class Generic < ::Nanoc::Error
end

class BinaryLayout < Generic
def initialize(content_filename)
super("The layout file '#{content_filename}' is a binary file, but layouts can only be textual")
end
end

class MultipleMetaFiles < Generic
def initialize(meta_filenames, basename)
super("Found #{meta_filenames.size} meta files for #{basename}; expected 0 or 1")
end
end

class MultipleContentFiles < Generic
def initialize(content_filenames, basename)
super("Found #{content_filenames.size} content files for #{basename}; expected 0 or 1")
end
end

class InvalidFormat < Generic
def initialize(content_filename)
super("The file '#{content_filename}' appears to start with a metadata section (three or five dashes at the top) but it does not seem to be in the correct format.")
end
end

class UnparseableMetadata < Generic
def initialize(filename, error)
super("Could not parse metadata for #{filename}: #{error.message}")
end
end

class InvalidMetadata < Generic
def initialize(filename, klass)
super("The file #{filename} has invalid metadata (expected key-value pairs, found #{klass} instead)")
end
end

class InvalidEncoding < Generic
def initialize(filename, encoding)
super("Could not read #{filename} because the file is not valid #{encoding}.")
end
end

class FileUnreadable < Generic
def initialize(filename, error)
super("Could not read #{filename}: #{error.inspect}")
end
end
end
end
2 changes: 1 addition & 1 deletion test/cli/commands/test_create_site.rb
Expand Up @@ -75,7 +75,7 @@ def test_default_encoding
FileUtils.cd('foo') do
# Try with encoding = default encoding = utf-8
File.open('content/index.html', 'w') { |io| io.write('Hello ' + 0xD6.chr + "!\n") }
exception = assert_raises(RuntimeError) do
exception = assert_raises(Nanoc::DataSources::Filesystem::Errors::InvalidEncoding) do
Nanoc::Int::SiteLoader.new.new_from_cwd
end
assert_equal 'Could not read content/index.html because the file is not valid UTF-8.', exception.message
Expand Down
10 changes: 5 additions & 5 deletions test/data_sources/test_filesystem.rb
Expand Up @@ -135,7 +135,7 @@ def test_load_binary_layouts
File.open('foo/stuff.dat', 'w') { |io| io.write('random binary data') }

# Load
assert_raises(RuntimeError) do
assert_raises(Nanoc::DataSources::Filesystem::Errors::BinaryLayout) do
data_source.send(:load_objects, 'foo', Nanoc::Int::Layout)
end
end
Expand Down Expand Up @@ -642,7 +642,7 @@ def test_all_split_files_in_with_multiple_content_files
end

# Check
assert_raises RuntimeError do
assert_raises(Nanoc::DataSources::Filesystem::Errors::MultipleContentFiles) do
data_source.send(:all_split_files_in, '.')
end
end
Expand Down Expand Up @@ -829,7 +829,7 @@ def test_parse_embedded_invalid_2
data_source = Nanoc::DataSources::Filesystem.new(nil, nil, nil, nil)

# Parse it
assert_raises(RuntimeError) do
assert_raises(Nanoc::DataSources::Filesystem::Errors::InvalidFormat) do
data_source.instance_eval { parse('test.html', nil) }
end
end
Expand Down Expand Up @@ -981,7 +981,7 @@ def test_parse_internal_bad_metadata

data_source = Nanoc::DataSources::Filesystem.new(nil, nil, nil, nil)

assert_raises(Nanoc::DataSources::Filesystem::InvalidMetadataError) do
assert_raises(Nanoc::DataSources::Filesystem::Errors::InvalidMetadata) do
data_source.instance_eval { parse('test.html', nil) }
end
end
Expand All @@ -992,7 +992,7 @@ def test_parse_external_bad_metadata

data_source = Nanoc::DataSources::Filesystem.new(nil, nil, nil, nil)

assert_raises(Nanoc::DataSources::Filesystem::InvalidMetadataError) do
assert_raises(Nanoc::DataSources::Filesystem::Errors::InvalidMetadata) do
data_source.instance_eval { parse('test.html', 'test.yaml') }
end
end
Expand Down

0 comments on commit 3793a07

Please sign in to comment.