Browse Source

Remove error-chain

Closes #576
index-subcmd
Vincent Prouillet 5 years ago
parent
commit
5caf24f06c
23 changed files with 175 additions and 87 deletions
  1. +1
    -2
      Cargo.lock
  2. +1
    -0
      components/config/Cargo.toml
  3. +13
    -11
      components/config/src/config.rs
  4. +5
    -3
      components/config/src/lib.rs
  5. +8
    -12
      components/config/src/theme.rs
  6. +0
    -1
      components/errors/Cargo.toml
  7. +88
    -13
      components/errors/src/lib.rs
  8. +5
    -5
      components/front_matter/src/lib.rs
  9. +2
    -2
      components/imageproc/src/lib.rs
  10. +3
    -3
      components/library/src/content/page.rs
  11. +3
    -3
      components/library/src/content/section.rs
  12. +2
    -2
      components/library/src/pagination/mod.rs
  13. +5
    -5
      components/library/src/taxonomies/mod.rs
  14. +2
    -2
      components/rendering/src/shortcode.rs
  15. +1
    -1
      components/rendering/tests/markdown.rs
  16. +5
    -5
      components/site/src/lib.rs
  17. +0
    -1
      components/templates/Cargo.toml
  18. +0
    -2
      components/templates/src/global_fns/mod.rs
  19. +2
    -2
      components/templates/src/lib.rs
  20. +18
    -4
      components/utils/src/fs.rs
  21. +1
    -0
      docs/templates/page.html
  22. +5
    -5
      src/cmd/serve.rs
  23. +5
    -3
      src/console.rs

+ 1
- 2
Cargo.lock View File

@@ -342,6 +342,7 @@ dependencies = [
"serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"utils 0.1.0",
]

[[package]]
@@ -616,7 +617,6 @@ dependencies = [
name = "errors"
version = "0.1.0"
dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2229,7 +2229,6 @@ dependencies = [
"base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"config 0.1.0",
"csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"errors 0.1.0",
"imageproc 0.1.0",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",


+ 1
- 0
components/config/Cargo.toml View File

@@ -13,3 +13,4 @@ lazy_static = "1"
syntect = "3"

errors = { path = "../errors" }
utils = { path = "../utils" }

+ 13
- 11
components/config/src/config.rs View File

@@ -1,6 +1,4 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};

use chrono::Utc;
@@ -9,9 +7,10 @@ use syntect::parsing::{SyntaxSet, SyntaxSetBuilder};
use toml;
use toml::Value as Toml;

use errors::{Result, ResultExt};
use errors::Result;
use highlighting::THEME_SET;
use theme::Theme;
use utils::fs::read_file_with_error;

// We want a default base url for tests
static DEFAULT_BASE_URL: &'static str = "http://a-website.com";
@@ -66,7 +65,13 @@ impl Taxonomy {

impl Default for Taxonomy {
fn default() -> Taxonomy {
Taxonomy { name: String::new(), paginate_by: None, paginate_path: None, rss: false, lang: None }
Taxonomy {
name: String::new(),
paginate_by: None,
paginate_path: None,
rss: false,
lang: None,
}
}
}

@@ -172,15 +177,12 @@ impl Config {

/// Parses a config file from the given path
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Config> {
let mut content = String::new();
let path = path.as_ref();
let file_name = path.file_name().unwrap();
File::open(path)
.chain_err(|| {
format!("No `{:?}` file found. Are you in the right directory?", file_name)
})?
.read_to_string(&mut content)?;

let content = read_file_with_error(
path,
&format!("No `{:?}` file found. Are you in the right directory?", file_name),
)?;
Config::parse(&content)
}



+ 5
- 3
components/config/src/lib.rs View File

@@ -1,14 +1,16 @@
#[macro_use]
extern crate serde_derive;
extern crate toml;
#[macro_use]
extern crate errors;
extern crate chrono;
extern crate globset;
extern crate toml;
#[macro_use]
extern crate lazy_static;
extern crate syntect;

#[macro_use]
extern crate errors;
extern crate utils;

mod config;
pub mod highlighting;
mod theme;


+ 8
- 12
components/config/src/theme.rs View File

@@ -1,11 +1,10 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;

use toml::Value as Toml;

use errors::{Result, ResultExt};
use errors::Result;
use utils::fs::read_file_with_error;

/// Holds the data from a `theme.toml` file.
/// There are other fields than `extra` in it but Zola
@@ -40,15 +39,12 @@ impl Theme {

/// Parses a theme file from the given path
pub fn from_file(path: &PathBuf) -> Result<Theme> {
let mut content = String::new();
File::open(path)
.chain_err(|| {
"No `theme.toml` file found. \
Is the `theme` defined in your `config.toml present in the `themes` directory \
and does it have a `theme.toml` inside?"
})?
.read_to_string(&mut content)?;

let content = read_file_with_error(
path,
"No `theme.toml` file found. \
Is the `theme` defined in your `config.toml present in the `themes` directory \
and does it have a `theme.toml` inside?",
)?;
Theme::parse(&content)
}
}

+ 0
- 1
components/errors/Cargo.toml View File

@@ -4,7 +4,6 @@ version = "0.1.0"
authors = ["Vincent Prouillet <prouillet.vincent@gmail.com>"]

[dependencies]
error-chain = "0.12"
tera = "0.11"
toml = "0.4"
image = "0.20"


+ 88
- 13
components/errors/src/lib.rs View File

@@ -1,26 +1,101 @@
#![allow(unused_doc_comments)]

#[macro_use]
extern crate error_chain;
extern crate image;
extern crate syntect;
extern crate tera;
extern crate toml;

error_chain! {
errors {}
use std::convert::Into;
use std::error::Error as StdError;
use std::fmt;

#[derive(Debug)]
pub enum ErrorKind {
Msg(String),
Tera(tera::Error),
Io(::std::io::Error),
Toml(toml::de::Error),
Image(image::ImageError),
Syntect(syntect::LoadingError),
}

/// The Error type
#[derive(Debug)]
pub struct Error {
/// Kind of error
pub kind: ErrorKind,
pub source: Option<Box<dyn StdError>>,
}
unsafe impl Sync for Error {}
unsafe impl Send for Error {}

impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.source.as_ref().map(|c| &**c)
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.kind {
ErrorKind::Msg(ref message) => write!(f, "{}", message),
ErrorKind::Tera(ref e) => write!(f, "{}", e),
ErrorKind::Io(ref e) => write!(f, "{}", e),
ErrorKind::Toml(ref e) => write!(f, "{}", e),
ErrorKind::Image(ref e) => write!(f, "{}", e),
ErrorKind::Syntect(ref e) => write!(f, "{}", e),
}
}
}

links {
Tera(tera::Error, tera::ErrorKind);
impl Error {
/// Creates generic error
pub fn msg(value: impl ToString) -> Self {
Self { kind: ErrorKind::Msg(value.to_string()), source: None }
}

foreign_links {
Io(::std::io::Error);
Toml(toml::de::Error);
Image(image::ImageError);
Syntect(syntect::LoadingError);
/// Creates generic error with a cause
pub fn chain(value: impl ToString, source: impl Into<Box<dyn StdError>>) -> Self {
Self { kind: ErrorKind::Msg(value.to_string()), source: Some(source.into()) }
}
}


impl From<&str> for Error {
fn from(e: &str) -> Self {
Self::msg(e)
}
}
impl From<String> for Error {
fn from(e: String) -> Self {
Self::msg(e)
}
}
impl From<toml::de::Error> for Error {
fn from(e: toml::de::Error) -> Self {
Self { kind: ErrorKind::Toml(e), source: None }
}
}
impl From<syntect::LoadingError> for Error {
fn from(e: syntect::LoadingError) -> Self {
Self { kind: ErrorKind::Syntect(e), source: None }
}
}
impl From<tera::Error> for Error {
fn from(e: tera::Error) -> Self {
Self { kind: ErrorKind::Tera(e), source: None }
}
}
impl From<::std::io::Error> for Error {
fn from(e: ::std::io::Error) -> Self {
Self { kind: ErrorKind::Io(e), source: None }
}
}
impl From<image::ImageError> for Error {
fn from(e: image::ImageError) -> Self {
Self { kind: ErrorKind::Image(e), source: None }
}
}
/// Convenient wrapper around std::Result.
pub type Result<T> = ::std::result::Result<T, Error>;

// So we can use bail! in all other crates
#[macro_export]


+ 5
- 5
components/front_matter/src/lib.rs View File

@@ -12,7 +12,7 @@ extern crate toml;
extern crate errors;
extern crate utils;

use errors::{Result, ResultExt};
use errors::{Result, Error};
use regex::Regex;
use std::path::Path;

@@ -71,8 +71,8 @@ pub fn split_section_content(
content: &str,
) -> Result<(SectionFrontMatter, String)> {
let (front_matter, content) = split_content(file_path, content)?;
let meta = SectionFrontMatter::parse(&front_matter).chain_err(|| {
format!("Error when parsing front matter of section `{}`", file_path.to_string_lossy())
let meta = SectionFrontMatter::parse(&front_matter).map_err(|e| {
Error::chain(format!("Error when parsing front matter of section `{}`", file_path.to_string_lossy()), e)
})?;
Ok((meta, content))
}
@@ -81,8 +81,8 @@ pub fn split_section_content(
/// Returns a parsed `PageFrontMatter` and the rest of the content
pub fn split_page_content(file_path: &Path, content: &str) -> Result<(PageFrontMatter, String)> {
let (front_matter, content) = split_content(file_path, content)?;
let meta = PageFrontMatter::parse(&front_matter).chain_err(|| {
format!("Error when parsing front matter of page `{}`", file_path.to_string_lossy())
let meta = PageFrontMatter::parse(&front_matter).map_err(|e| {
Error::chain(format!("Error when parsing front matter of page `{}`", file_path.to_string_lossy()), e)
})?;
Ok((meta, content))
}


+ 2
- 2
components/imageproc/src/lib.rs View File

@@ -20,7 +20,7 @@ use image::{FilterType, GenericImageView};
use rayon::prelude::*;
use regex::Regex;

use errors::{Result, ResultExt};
use errors::{Result, Error};
use utils::fs as ufs;

static RESIZED_SUBDIR: &'static str = "processed_images";
@@ -456,7 +456,7 @@ impl Processor {
let target =
self.resized_path.join(Self::op_filename(*hash, op.collision_id, op.format));
op.perform(&self.content_path, &target)
.chain_err(|| format!("Failed to process image: {}", op.source))
.map_err(|e| Error::chain(format!("Failed to process image: {}", op.source), e))
})
.collect::<Result<()>>()
}


+ 3
- 3
components/library/src/content/page.rs View File

@@ -8,7 +8,7 @@ use slug::slugify;
use tera::{Context as TeraContext, Tera};

use config::Config;
use errors::{Result, ResultExt};
use errors::{Result, Error};
use front_matter::{split_page_content, InsertAnchor, PageFrontMatter};
use library::Library;
use rendering::{render_content, Header, RenderContext};
@@ -234,7 +234,7 @@ impl Page {
context.tera_context.insert("page", &SerializingPage::from_page_basic(self, None));

let res = render_content(&self.raw_content, &context)
.chain_err(|| format!("Failed to render content of {}", self.file.path.display()))?;
.map_err(|e| Error::chain(format!("Failed to render content of {}", self.file.path.display()), e))?;

self.summary = res.summary_len.map(|l| res.body[0..l].to_owned());
self.content = res.body;
@@ -258,7 +258,7 @@ impl Page {
context.insert("lang", &self.lang);

render_template(&tpl_name, tera, &context, &config.theme)
.chain_err(|| format!("Failed to render page '{}'", self.file.path.display()))
.map_err(|e| Error::chain(format!("Failed to render page '{}'", self.file.path.display()), e))
}

/// Creates a vectors of asset URLs.


+ 3
- 3
components/library/src/content/section.rs View File

@@ -5,7 +5,7 @@ use slotmap::Key;
use tera::{Context as TeraContext, Tera};

use config::Config;
use errors::{Result, ResultExt};
use errors::{Result, Error};
use front_matter::{split_section_content, SectionFrontMatter};
use rendering::{render_content, Header, RenderContext};
use utils::fs::{find_related_assets, read_file};
@@ -172,7 +172,7 @@ impl Section {
context.tera_context.insert("section", &SerializingSection::from_section_basic(self, None));

let res = render_content(&self.raw_content, &context)
.chain_err(|| format!("Failed to render content of {}", self.file.path.display()))?;
.map_err(|e| Error::chain(format!("Failed to render content of {}", self.file.path.display()), e))?;
self.content = res.body;
self.toc = res.toc;
Ok(())
@@ -190,7 +190,7 @@ impl Section {
context.insert("lang", &self.lang);

render_template(tpl_name, tera, &context, &config.theme)
.chain_err(|| format!("Failed to render section '{}'", self.file.path.display()))
.map_err(|e| Error::chain(format!("Failed to render section '{}'", self.file.path.display()), e))
}

/// Is this the index section?


+ 2
- 2
components/library/src/pagination/mod.rs View File

@@ -4,7 +4,7 @@ use slotmap::Key;
use tera::{to_value, Context, Tera, Value};

use config::Config;
use errors::{Result, ResultExt};
use errors::{Result, Error};
use utils::templates::render_template;

use content::{Section, SerializingPage, SerializingSection};
@@ -222,7 +222,7 @@ impl<'a> Paginator<'a> {
context.insert("paginator", &self.build_paginator_context(pager));

render_template(&self.template, tera, &context, &config.theme)
.chain_err(|| format!("Failed to render pager {}", pager.index))
.map_err(|e| Error::chain(format!("Failed to render pager {}", pager.index), e))
}
}



+ 5
- 5
components/library/src/taxonomies/mod.rs View File

@@ -5,7 +5,7 @@ use slug::slugify;
use tera::{Context, Tera};

use config::{Config, Taxonomy as TaxonomyConfig};
use errors::{Result, ResultExt};
use errors::{Result, Error};
use utils::templates::render_template;

use content::SerializingPage;
@@ -145,7 +145,7 @@ impl Taxonomy {
context.insert("current_path", &format!("/{}/{}", self.kind.name, item.slug));

render_template(&format!("{}/single.html", self.kind.name), tera, &context, &config.theme)
.chain_err(|| format!("Failed to render single term {} page.", self.kind.name))
.map_err(|e| Error::chain(format!("Failed to render single term {} page.", self.kind.name), e))
}

pub fn render_all_terms(
@@ -164,7 +164,7 @@ impl Taxonomy {
context.insert("current_path", &self.kind.name);

render_template(&format!("{}/list.html", self.kind.name), tera, &context, &config.theme)
.chain_err(|| format!("Failed to render a list of {} page.", self.kind.name))
.map_err(|e| Error::chain(format!("Failed to render a list of {} page.", self.kind.name), e))
}

pub fn to_serialized<'a>(&'a self, library: &'a Library) -> SerializedTaxonomy<'a> {
@@ -334,7 +334,7 @@ mod tests {
let err = taxonomies.unwrap_err();
// no path as this is created by Default
assert_eq!(
err.description(),
format!("{}", err),
"Page `` has taxonomy `tags` which is not defined in config.toml"
);
}
@@ -442,7 +442,7 @@ mod tests {
let err = taxonomies.unwrap_err();
// no path as this is created by Default
assert_eq!(
err.description(),
format!("{}", err),
"Page `` has taxonomy `tags` which is not available in that language"
);
}


+ 2
- 2
components/rendering/src/shortcode.rs View File

@@ -4,7 +4,7 @@ use regex::Regex;
use tera::{to_value, Context, Map, Value};

use context::RenderContext;
use errors::{Result, ResultExt};
use errors::{Result, Error};

// This include forces recompiling this source file if the grammar file changes.
// Uncomment it when doing changes to the .pest file
@@ -116,7 +116,7 @@ fn render_shortcode(
let res = context
.tera
.render(&tpl_name, &tera_context)
.chain_err(|| format!("Failed to render {} shortcode", name))?;
.map_err(|e| Error::chain(format!("Failed to render {} shortcode", name), e))?;

// Small hack to avoid having multiple blank lines because of Tera tags for example
// A blank like will cause the markdown parser to think we're out of HTML and start looking


+ 1
- 1
components/rendering/tests/markdown.rs View File

@@ -660,7 +660,7 @@ fn can_show_error_message_for_invalid_external_links() {
let res = render_content("[a link](http://google.comy)", &context);
assert!(res.is_err());
let err = res.unwrap_err();
assert!(err.description().contains("Link http://google.comy is not valid"));
assert!(format!("{}", err).contains("Link http://google.comy is not valid"));
}

#[test]


+ 5
- 5
components/site/src/lib.rs View File

@@ -30,7 +30,7 @@ use sass_rs::{compile_file, Options as SassOptions, OutputStyle};
use tera::{Context, Tera};

use config::{get_config, Config};
use errors::{Result, ResultExt};
use errors::{Result, Error};
use front_matter::InsertAnchor;
use library::{
find_taxonomies, sort_actual_pages_by_date, Library, Page, Paginator, Section, Taxonomy,
@@ -87,7 +87,7 @@ impl Site {
format!("{}/{}", path.to_string_lossy().replace("\\", "/"), "templates/**/*.*ml");
// Only parsing as we might be extending templates from themes and that would error
// as we haven't loaded them yet
let mut tera = Tera::parse(&tpl_glob).chain_err(|| "Error parsing templates")?;
let mut tera = Tera::parse(&tpl_glob).map_err(|e| Error::chain("Error parsing templates", e))?;
if let Some(theme) = config.theme.clone() {
// Grab data from the extra section of the theme
config.merge_with_theme(&path.join("themes").join(&theme).join("theme.toml"))?;
@@ -104,9 +104,9 @@ impl Site {
format!("themes/{}/templates/**/*.*ml", theme)
);
let mut tera_theme =
Tera::parse(&theme_tpl_glob).chain_err(|| "Error parsing templates from themes")?;
Tera::parse(&theme_tpl_glob).map_err(|e| Error::chain("Error parsing templates from themes", e))?;
rewrite_theme_paths(&mut tera_theme, &theme);
// TODO: same as below
// TODO: we do that twice, make it dry?
if theme_path.join("templates").join("robots.txt").exists() {
tera_theme
.add_template_file(theme_path.join("templates").join("robots.txt"), None)?;
@@ -470,7 +470,7 @@ impl Site {
pub fn clean(&self) -> Result<()> {
if self.output_path.exists() {
// Delete current `public` directory so we can start fresh
remove_dir_all(&self.output_path).chain_err(|| "Couldn't delete output directory")?;
remove_dir_all(&self.output_path).map_err(|e| Error::chain("Couldn't delete output directory", e))?;
}

Ok(())


+ 0
- 1
components/templates/Cargo.toml View File

@@ -11,7 +11,6 @@ pulldown-cmark = "0.2"
toml = "0.4"
csv = "1"
serde_json = "1.0"
error-chain = "0.12"
reqwest = "0.9"
url = "1.5"



+ 0
- 2
components/templates/src/global_fns/mod.rs View File

@@ -1,5 +1,3 @@
extern crate error_chain;

use std::collections::HashMap;
use std::sync::{Arc, Mutex};



+ 2
- 2
components/templates/src/lib.rs View File

@@ -25,7 +25,7 @@ pub mod global_fns;

use tera::{Context, Tera};

use errors::{Result, ResultExt};
use errors::{Result, Error};

lazy_static! {
pub static ref ZOLA_TERA: Tera = {
@@ -57,5 +57,5 @@ pub fn render_redirect_template(url: &str, tera: &Tera) -> Result<String> {
context.insert("url", &url);

tera.render("internal/alias.html", &context)
.chain_err(|| format!("Failed to render alias for '{}'", url))
.map_err(|e| Error::chain(format!("Failed to render alias for '{}'", url), e))
}

+ 18
- 4
components/utils/src/fs.rs View File

@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
use std::time::SystemTime;
use walkdir::WalkDir;

use errors::{Result, ResultExt};
use errors::{Result, Error};

pub fn is_path_in_directory(parent: &Path, path: &Path) -> Result<bool> {
let canonical_path = path
@@ -19,7 +19,8 @@ pub fn is_path_in_directory(parent: &Path, path: &Path) -> Result<bool> {

/// Create a file with the content given
pub fn create_file(path: &Path, content: &str) -> Result<()> {
let mut file = File::create(&path).chain_err(|| format!("Failed to create {:?}", path))?;
let mut file = File::create(&path)
.map_err(|e| Error::chain(format!("Failed to create {:?}", path), e))?;
file.write_all(content.as_bytes())?;
Ok(())
}
@@ -37,7 +38,7 @@ pub fn ensure_directory_exists(path: &Path) -> Result<()> {
pub fn create_directory(path: &Path) -> Result<()> {
if !path.exists() {
create_dir_all(path)
.chain_err(|| format!("Was not able to create folder {}", path.display()))?;
.map_err(|e| Error::chain(format!("Was not able to create folder {}", path.display()), e))?;
}
Ok(())
}
@@ -46,7 +47,7 @@ pub fn create_directory(path: &Path) -> Result<()> {
pub fn read_file(path: &Path) -> Result<String> {
let mut content = String::new();
File::open(path)
.chain_err(|| format!("Failed to open '{:?}'", path.display()))?
.map_err(|e| Error::chain(format!("Failed to open '{:?}'", path.display()), e))?
.read_to_string(&mut content)?;

// Remove utf-8 BOM if any.
@@ -57,6 +58,19 @@ pub fn read_file(path: &Path) -> Result<String> {
Ok(content)
}

/// Return the content of a file, with error handling added.
/// The default error message is overwritten by the message given.
/// That means it is allocation 2 strings, oh well
pub fn read_file_with_error(path: &Path, message: &str) -> Result<String> {
let res = read_file(&path);
if res.is_ok() {
return res;
}
let mut err = Error::msg(message);
err.source = res.unwrap_err().source;
Err(err)
}

/// Looks into the current folder for the path and see if there's anything that is not a .md
/// file. Those will be copied next to the rendered .html file
pub fn find_related_assets(path: &Path) -> Vec<PathBuf> {


+ 1
- 0
docs/templates/page.html View File

@@ -4,4 +4,5 @@
{% block doc_content %}
<h1>{{page.title}}</h1>
{{page.content | safe}}
{{hey}}
{% endblock doc_content %}

+ 5
- 5
src/cmd/serve.rs View File

@@ -36,7 +36,7 @@ use ctrlc;
use notify::{watcher, RecursiveMode, Watcher};
use ws::{Message, Sender, WebSocket};

use errors::{Result, ResultExt};
use errors::{Result, Error as ZolaError};
use site::Site;
use utils::fs::copy_file;

@@ -179,23 +179,23 @@ pub fn serve(
let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap();
watcher
.watch("content/", RecursiveMode::Recursive)
.chain_err(|| "Can't watch the `content` folder. Does it exist?")?;
.map_err(|e| ZolaError::chain("Can't watch the `content` folder. Does it exist?", e))?;
watcher
.watch(config_file, RecursiveMode::Recursive)
.chain_err(|| "Can't watch the `config` file. Does it exist?")?;
.map_err(|e| ZolaError::chain("Can't watch the `config` file. Does it exist?", e))?;

if Path::new("static").exists() {
watching_static = true;
watcher
.watch("static/", RecursiveMode::Recursive)
.chain_err(|| "Can't watch the `static` folder.")?;
.map_err(|e| ZolaError::chain("Can't watch the `static` folder.", e))?;
}

if Path::new("templates").exists() {
watching_templates = true;
watcher
.watch("templates/", RecursiveMode::Recursive)
.chain_err(|| "Can't watch the `templates` folder.")?;
.map_err(|e| ZolaError::chain("Can't watch the `templates` folder.", e))?;
}

// Sass support is optional so don't make it an error to no have a sass folder


+ 5
- 3
src/console.rs View File

@@ -1,4 +1,5 @@
use std::env;
use std::error::Error as StdError;
use std::io::Write;
use std::time::Instant;

@@ -6,7 +7,6 @@ use atty;
use chrono::Duration;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

use errors::Error;
use site::Site;

lazy_static! {
@@ -91,13 +91,15 @@ pub fn report_elapsed_time(instant: Instant) {
}

/// Display an error message and the actual error(s)
pub fn unravel_errors(message: &str, error: &Error) {
pub fn unravel_errors(message: &str, error: &StdError) {
if !message.is_empty() {
self::error(message);
}
self::error(&format!("Error: {}", error));
for e in error.iter().skip(1) {
let mut cause = error.source();
while let Some(e) = cause {
self::error(&format!("Reason: {}", e));
cause = e.source();
}
}



Loading…
Cancel
Save