Skip to content

Commit

Permalink
Fix error messages in hot reloading: Only print message once
Browse files Browse the repository at this point in the history
  • Loading branch information
fschutt committed Dec 25, 2018
1 parent f81d1a6 commit dc7a940
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 40 deletions.
27 changes: 11 additions & 16 deletions azul-css-parser/src/css.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ pub enum CssParseErrorInner<'a> {
/// Error parsing dynamic CSS property, such as
/// `#div { width: {{ my_id }} /* no default case */ }`
DynamicCssParseError(DynamicCssParseError<'a>),
/// Error during parsing the value of a field
/// (Css is parsed eagerly, directly converted to strongly typed values
/// as soon as possible)
UnexpectedValue(CssParsingError<'a>),
/// Error while parsing a pseudo selector (like `:aldkfja`)
PseudoSelectorParseError(CssPseudoSelectorParseError<'a>),
/// The path has to be either `*`, `div`, `p` or something like that
Expand All @@ -56,14 +52,12 @@ impl_display!{ CssParseErrorInner<'a>, {
ParseError(e) => format!("Parse Error: {:?}", e),
UnclosedBlock => "Unclosed block",
MalformedCss => "Malformed Css",
DynamicCssParseError(e) => format!("Dynamic parsing error: {}", e),
UnexpectedValue(e) => format!("Unexpected value: {}", e),
DynamicCssParseError(e) => format!("Error parsing dynamic CSS property: {}", e),
PseudoSelectorParseError(e) => format!("Failed to parse pseudo-selector: {}", e),
NodeTypePath(e) => format!("Failed to parse CSS selector path: {}", e),
UnknownPropertyKey(k, v) => format!("Unknown CSS key: \"{}: {}\"", k, v),
}}

impl_from! { CssParsingError<'a>, CssParseErrorInner::UnexpectedValue }
impl_from! { DynamicCssParseError<'a>, CssParseErrorInner::DynamicCssParseError }
impl_from! { CssPseudoSelectorParseError<'a>, CssParseErrorInner::PseudoSelectorParseError }
impl_from! { NodeTypePathParseError<'a>, CssParseErrorInner::NodeTypePath }
Expand Down Expand Up @@ -152,7 +146,7 @@ pub struct ErrorLocation {

impl<'a> fmt::Display for CssParseError<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "CSS error at line {}:{}:\r\n{}", self.location.line, self.location.column, self.error)
write!(f, "CSS error at line {}:{}: {}", self.location.line, self.location.column, self.error)
}
}

Expand All @@ -161,20 +155,21 @@ pub fn new_from_str<'a>(css_string: &'a str) -> Result<Css, CssParseError<'a>> {
match new_from_str_inner(css_string, &mut tokenizer) {
Ok(css) => Ok(css),
Err(e) => {
let error_location = tokenizer.pos();
let mut line_number = 0;
let mut total_characters = 0;
let error_location = tokenizer.pos().saturating_sub(1);
let line_number: usize = css_string[0..error_location].lines().count();

for line in css_string[0..error_location].lines() {
line_number += 1;
total_characters += line.chars().count();
}
// Rust doesn't count "\n" as a character, so we have to add the line number count on top
let total_characters: usize = css_string[0..error_location].lines().take(line_number.saturating_sub(1)).map(|line| line.chars().count()).sum();
let total_characters = total_characters + line_number;
/*println!("line_number: {} error location: {}, total characters: {}", line_number,
error_location, total_characters);*/
let characters_in_line = (error_location + 2) - total_characters;

let characters_in_line = error_location - total_characters;
let error_location = ErrorLocation {
line: line_number,
column: characters_in_line,
};

Err(CssParseError {
error: e,
location: error_location,
Expand Down
5 changes: 4 additions & 1 deletion azul-css-parser/src/hot_reloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ impl HotReloadHandler for HotReloader {
.map_err(|e| format!("Io error: \"{}\" when loading file \"{}\"", e, self.file_path.to_str().unwrap_or("")))?;

::css::new_from_str(&reloaded_css)
.map_err(|e| format!("Parse error \"{}\":\r\n{}\n", self.file_path.to_str().unwrap_or(""), e))
.map_err(|e| {
let file_name = self.file_path.file_name().and_then(|os_str| Some(os_str.to_string_lossy())).unwrap_or_default();
format!("{}: {}", file_name, e)
})
}

fn get_reload_interval(&self) -> Duration {
Expand Down
61 changes: 39 additions & 22 deletions azul/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ impl<T: Layout> App<T> {

#[cfg(debug_assertions)]
let mut last_style_reload = Instant::now();
#[cfg(debug_assertions)]
let mut should_print_css_error = true;

while !self.windows.is_empty() {

Expand Down Expand Up @@ -353,7 +355,7 @@ impl<T: Layout> App<T> {
}

#[cfg(debug_assertions)] {
hot_reload_css(&mut self.windows, &mut last_style_reload, &mut awakened_task)
hot_reload_css(&mut self.windows, &mut last_style_reload, &mut should_print_css_error, &mut awakened_task)
}

// Close windows if necessary
Expand Down Expand Up @@ -539,31 +541,46 @@ enum WindowCloseEvent {
NoCloseEvent,
}

/// Returns if there was an error with the CSS reloading, necessary so that the error message is only printed once
#[cfg(debug_assertions)]
fn hot_reload_css<T: Layout>(windows: &mut [Window<T>], last_style_reload: &mut Instant, awakened_tasks: &mut [bool]) {
fn hot_reload_css<T: Layout>(
windows: &mut [Window<T>],
last_style_reload: &mut Instant,
should_print_error: &mut bool,
awakened_tasks: &mut [bool])
{
for (window_idx, window) in windows.iter_mut().enumerate() {
// Hot-reload a style if necessary
if let Some(ref mut hot_reloader) = window.css_loader {
if Instant::now() - *last_style_reload > hot_reloader.get_reload_interval() {
match hot_reloader.reload_style() {
Ok(mut new_css) => {
new_css.sort_by_specificity();
window.css = new_css;
*last_style_reload = Instant::now();
window.events_loop.create_proxy().wakeup().unwrap_or(());
awakened_tasks[window_idx] = true;
},
Err(why) => {
#[cfg(feature = "logging")] {
error!("Failed to hot-reload style: {}", why);
}
#[cfg(not(feature = "logging"))] {
println!("Failed to hot-reload style: {}", why);
}
},
};
}
let hot_reloader = match window.css_loader.as_mut() {
None => continue,
Some(s) => s,
};

let should_reload = Instant::now() - *last_style_reload > hot_reloader.get_reload_interval();

if !should_reload {
return;
}

match hot_reloader.reload_style() {
Ok(mut new_css) => {
new_css.sort_by_specificity();
window.css = new_css;
if !(*should_print_error) {
println!("CSS parsed without errors, continuing hot-reloading.");
}
*last_style_reload = Instant::now();
window.events_loop.create_proxy().wakeup().unwrap_or(());
awakened_tasks[window_idx] = true;
*should_print_error = true;
},
Err(why) => {
if *should_print_error {
println!("{}", why);
}
*should_print_error = false;
},
};
}
}

Expand Down
3 changes: 2 additions & 1 deletion examples/hot_reload.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
justify-content: flex-start;
}


#red {
background-color: #BF0C2B;
color: white;
Expand All @@ -17,7 +18,7 @@

#sub-wrapper {
flex-direction: column;
width: 400px;
width: 200px;
box-shadow: 0px 0px 50px black;
position: relative;
top: 40px;
Expand Down

0 comments on commit dc7a940

Please sign in to comment.