file: Add more context to errors from file(DOWNLOAD)
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 78dda57..5dec19f 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2131,7 +2131,8 @@
   if (!file.empty()) {
     fout.open(file.c_str(), std::ios::binary);
     if (!fout) {
-      status.SetError("DOWNLOAD cannot open file for write.");
+      status.SetError(cmStrCat("DOWNLOAD cannot open file for write\n",
+                               "  file: \"", file, '"'));
       return false;
     }
   }
@@ -2320,16 +2321,18 @@
   //
   if (hash) {
     if (res != CURLE_OK) {
-      status.SetError(cmStrCat(
-        "DOWNLOAD cannot compute hash on failed download\n"
-        "  status: [",
-        static_cast<int>(res), ";\"", ::curl_easy_strerror(res), "\"]"));
+      status.SetError(
+        cmStrCat("DOWNLOAD cannot compute hash on failed download\n"
+                 "  from url: \"",
+                 url, "\"\n  status: [", static_cast<int>(res), ";\"",
+                 ::curl_easy_strerror(res), "\"]"));
       return false;
     }
 
     std::string actualHash = hash->HashFile(file);
     if (actualHash.empty()) {
-      status.SetError("DOWNLOAD cannot compute hash on downloaded file");
+      status.SetError(cmStrCat("DOWNLOAD cannot compute hash on download\n",
+                               "  for file: \"", file, '"'));
       return false;
     }
 
@@ -2343,14 +2346,14 @@
       }
 
       status.SetError(cmStrCat("DOWNLOAD HASH mismatch\n"
-                               "  for file: [",
+                               "  for file: \"",
                                file,
-                               "]\n"
-                               "    expected hash: [",
+                               "\"\n"
+                               "    expected hash: \"",
                                expectedHash,
-                               "]\n"
-                               "      actual hash: [",
-                               actualHash, "]\n"));
+                               "\"\n"
+                               "      actual hash: \"",
+                               actualHash, "\"\n"));
       return false;
     }
   }
diff --git a/Tests/RunCMake/file-DOWNLOAD/RunCMakeTest.cmake b/Tests/RunCMake/file-DOWNLOAD/RunCMakeTest.cmake
index 11fee2f..8771cbe 100644
--- a/Tests/RunCMake/file-DOWNLOAD/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file-DOWNLOAD/RunCMakeTest.cmake
@@ -15,6 +15,8 @@
 run_cmake(TLS_VERSION-missing)
 run_cmake(pass-not-set)
 run_cmake(no-save-hash)
+run_cmake(failed-download)
+run_cmake(bad-file)
 
 run_cmake(basic)
 run_cmake(EXPECTED_HASH)
diff --git a/Tests/RunCMake/file-DOWNLOAD/bad-file-result.txt b/Tests/RunCMake/file-DOWNLOAD/bad-file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/bad-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-DOWNLOAD/bad-file-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/bad-file-stderr.txt
new file mode 100644
index 0000000..f5ac868
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/bad-file-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at bad-file.cmake:[0-9]+ \(file\):
+  file DOWNLOAD cannot open file for write
+
+    file: "."
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file-DOWNLOAD/bad-file.cmake b/Tests/RunCMake/file-DOWNLOAD/bad-file.cmake
new file mode 100644
index 0000000..74b7e3a
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/bad-file.cmake
@@ -0,0 +1,3 @@
+include(common.cmake)
+
+file(DOWNLOAD ${url} .)
diff --git a/Tests/RunCMake/file-DOWNLOAD/failed-download-result.txt b/Tests/RunCMake/file-DOWNLOAD/failed-download-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/failed-download-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-DOWNLOAD/failed-download-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/failed-download-stderr.txt
new file mode 100644
index 0000000..218127b
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/failed-download-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at failed-download.cmake:[0-9]+ \(file\):
+  file DOWNLOAD cannot compute hash on failed download
+
+    from url: "[^
+]*input.png_invalid"
+    status: \[37;"(Could not|Couldn't) read a file:// file"\]
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file-DOWNLOAD/failed-download.cmake b/Tests/RunCMake/file-DOWNLOAD/failed-download.cmake
new file mode 100644
index 0000000..aa9ac55
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/failed-download.cmake
@@ -0,0 +1,6 @@
+include(common.cmake)
+
+file(DOWNLOAD ${url}_invalid ${file}
+  EXPECTED_HASH SHA1=0123456789abcdef0123456789abcdef01234567
+  STATUS status
+)
diff --git a/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-stderr.txt
index 6682794..e53f8a2 100644
--- a/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-stderr.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-stderr.txt
@@ -1,9 +1,9 @@
 ^CMake Error at hash-mismatch.cmake:[0-9]+ \(file\):
   file DOWNLOAD HASH mismatch
 
-    for file: \[.*/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-build/output.png\]
-      expected hash: \[0123456789abcdef0123456789abcdef01234567\]
-        actual hash: \[67eee17f79d9ac557284fc0b8ad19f25723fb578\]
+    for file: ".*/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-build/output.png"
+      expected hash: "0123456789abcdef0123456789abcdef01234567"
+        actual hash: "67eee17f79d9ac557284fc0b8ad19f25723fb578"
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)