From 5b01772282e0872b72d430486e4753c5e8b86163 Mon Sep 17 00:00:00 2001
From: Anna Henningsen <anna@addaleax.net>
Date: Sun, 12 Apr 2020 18:55:03 +0200
Subject: [PATCH] src: use basename(argv0) for --trace-uncaught suggestion

Refs: https://github.com/nodejs/node/pull/32797#discussion_r407222290

PR-URL: https://github.com/nodejs/node/pull/32798
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
---
 src/node_errors.cc   |  9 +++++++--
 src/node_file.cc     | 16 ++++++++++++++++
 src/node_internals.h |  4 ++++
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/src/node_errors.cc b/src/node_errors.cc
index 9bae27550cec1b..4e13c24e15e1d0 100644
--- a/src/node_errors.cc
+++ b/src/node_errors.cc
@@ -375,8 +375,13 @@ static void ReportFatalException(Environment* env,
     }
 
     if (!env->options()->trace_uncaught) {
-      FPrintF(stderr, "(Use `node --trace-uncaught ...` to show "
-                      "where the exception was thrown)\n");
+      std::string argv0;
+      if (!env->argv().empty()) argv0 = env->argv()[0];
+      if (argv0.empty()) argv0 = "node";
+      FPrintF(stderr,
+              "(Use `%s --trace-uncaught ...` to show where the exception "
+              "was thrown)\n",
+              fs::Basename(argv0, ".exe"));
     }
   }
 
diff --git a/src/node_file.cc b/src/node_file.cc
index 0ce86287bb83e9..a1cb5cadd2f3eb 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -82,6 +82,22 @@ constexpr char kPathSeparator = '/';
 const char* const kPathSeparator = "\\/";
 #endif
 
+std::string Basename(const std::string& str, const std::string& extension) {
+  std::string ret = str;
+
+  // Remove everything leading up to and including the final path separator.
+  std::string::size_type pos = ret.find_last_of(kPathSeparator);
+  if (pos != std::string::npos) ret = ret.substr(pos + 1);
+
+  // Strip away the extension, if any.
+  if (ret.size() >= extension.size() &&
+      ret.substr(ret.size() - extension.size()) == extension) {
+    ret = ret.substr(0, ret.size() - extension.size());
+  }
+
+  return ret;
+}
+
 inline int64_t GetOffset(Local<Value> value) {
   return IsSafeJsInt(value) ? value.As<Integer>()->Value() : -1;
 }
diff --git a/src/node_internals.h b/src/node_internals.h
index 7dcbf65f8e698a..483574c090e953 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -394,6 +394,10 @@ BaseObjectPtr<AsyncWrap> CreateHeapSnapshotStream(
     Environment* env, HeapSnapshotPointer&& snapshot);
 }  // namespace heap
 
+namespace fs {
+std::string Basename(const std::string& str, const std::string& extension);
+}  // namespace fs
+
 }  // namespace node
 
 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS