From 777d5b297963f5547d0b4f75586374f1abfe87cf Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 11 Sep 2026 04:29:09 +0000 Subject: [PATCH] Report the whole build failure, not just its first line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `EmberCli::BuildError` was raised with `build_errors.first`, so everything the build tool wrote after the first line was dropped. The line naming the file that failed to build is rarely that first line — a Handlebars parse error, for instance, leads with `Build failed.` and names the file on the next line — which left the error reporting a line number with no file to look it up in. Join the failure's lines into the message instead, and set the same lines as the error's backtrace. The existing filtering is unchanged, so blank lines, JavaScript stack frames, deprecation warnings and `Building` notices still never reach the message; `build_errors` now chomps the lines it keeps, so a failure read from disk no longer carries the file's newlines into the message. This reporting is reached by the classic (non-Vite) blueprint only. There, `ember build --watch` runs in the background with its standard error redirected to the build error file, and `BuildMonitor` is what turns that file into an exception. An application built with the Vite blueprint goes through `Shell#compile` instead, where a failure is raised by `Runner#run!` as "`` failed with status N" before `BuildMonitor` is consulted, and `rake ember:compile` takes that same path for every blueprint. Neither of those is changed here. Closes #484 Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 9 ++++ lib/ember_cli/build_monitor.rb | 7 +-- spec/lib/ember_cli/build_monitor_spec.rb | 56 ++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e991a20..515746f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +main +------ + +* Report the whole `ember build` failure in the `EmberCli::BuildError` + message, instead of only its first line. The line naming the file that + failed to build is rarely the first one the build tool writes, so a parse + error was reported with its message and line number but no way to tell + which file it came from + 0.14.0 ------ diff --git a/lib/ember_cli/build_monitor.rb b/lib/ember_cli/build_monitor.rb index 75cbf448..2503f4fd 100644 --- a/lib/ember_cli/build_monitor.rb +++ b/lib/ember_cli/build_monitor.rb @@ -41,6 +41,7 @@ def error_file_exists? def build_errors error_lines. + map(&:chomp). reject { |line| is_blank_or_backtrace?(line) }. reject { |line| is_deprecation_warning?(line) }. reject { |line| is_building_notice?(line) } @@ -75,11 +76,11 @@ def error_file end def raise_build_error! - backtrace = build_errors.first - message = "#{name.inspect} has failed to build: #{backtrace}" + errors = build_errors + message = "#{name.inspect} has failed to build: #{errors.join("\n")}" error = BuildError.new(message) - error.set_backtrace(backtrace) + error.set_backtrace(errors) fail error end diff --git a/spec/lib/ember_cli/build_monitor_spec.rb b/spec/lib/ember_cli/build_monitor_spec.rb index a9338434..9a3ec98b 100644 --- a/spec/lib/ember_cli/build_monitor_spec.rb +++ b/spec/lib/ember_cli/build_monitor_spec.rb @@ -56,6 +56,62 @@ end end + context "when the error file describes the file that failed to build" do + it "raises a BuildError reporting every line of the failure" do + error_file = error_file_with_contents( + [ + "Build failed.", + "File: app/templates/application.hbs", + "Parse error on line 4:", + " at AStackTrace", + ]) + paths = build_paths(error_file) + monitor = EmberCli::BuildMonitor.new("app-name", paths) + + expect { monitor.check! }. + to raise_error( + EmberCli::BuildError, + %{"app-name" has failed to build: Build failed.\nFile: app/templates/application.hbs\nParse error on line 4:}, + ) + end + + it "sets the backtrace to the lines of the failure" do + error_file = error_file_with_contents( + [ + "File: app/templates/application.hbs", + "Parse error on line 4:", + ]) + paths = build_paths(error_file) + monitor = EmberCli::BuildMonitor.new("app-name", paths) + + expect { monitor.check! }.to raise_error(EmberCli::BuildError) do |error| + expect(error.backtrace).to eq( + [ + "File: app/templates/application.hbs", + "Parse error on line 4:", + ]) + end + end + end + + context "when the error file's lines end in newlines" do + it "raises a BuildError without the trailing newlines" do + error_file = error_file_with_contents( + [ + "File: app/templates/application.hbs\n", + "Parse error on line 4:\n", + ]) + paths = build_paths(error_file) + monitor = EmberCli::BuildMonitor.new("app-name", paths) + + expect { monitor.check! }. + to raise_error( + EmberCli::BuildError, + %{"app-name" has failed to build: File: app/templates/application.hbs\nParse error on line 4:}, + ) + end + end + context "when the error file only contains deprecation warnings" do it "does not raise a BuildError" do error_file = error_file_with_contents(