scripts: run_common: don't dump stack on unavailable runner

Originally reported in #23539 (though that seems to have been another
problem), west flash and friends are dumping stack when used with an
unconfigured runner.

Let's just promote the warning about this to an error. The idea that
this ever could have worked without explicit support has not worked
out in practice, to my knowledge.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
diff --git a/scripts/west_commands/run_common.py b/scripts/west_commands/run_common.py
index 1e91c1b..8f6eec1 100644
--- a/scripts/west_commands/run_common.py
+++ b/scripts/west_commands/run_common.py
@@ -8,7 +8,9 @@
 import argparse
 import logging
 from os import close, getcwd, path
+from pathlib import Path
 from subprocess import CalledProcessError
+import sys
 import tempfile
 import textwrap
 import traceback
@@ -146,7 +148,8 @@
 
     # Get a concrete ZephyrBinaryRunner subclass to use based on
     # runners.yaml and command line arguments.
-    runner_cls = use_runner_cls(command, board, user_args, runner_config)
+    runner_cls = use_runner_cls(command, board, user_args, runner_config,
+                                cache)
     runner_name = runner_cls.name()
 
     # Set up runner logging to delegate to west.log commands.
@@ -289,7 +292,7 @@
 
     return config
 
-def use_runner_cls(command, board, args, runner_config):
+def use_runner_cls(command, board, args, runner_config, cache):
     # Get the ZephyrBinaryRunner class from its name, and make sure it
     # supports the command. Print a message about the choice, and
     # return the class.
@@ -303,8 +306,14 @@
 
     available = runner_config.get('runners', [])
     if runner not in available:
-        log.wrn(f'runner {runner} is not configured for use with {board}, '
-                'this may not work')
+        if 'BOARD_DIR' in cache:
+            board_cmake = Path(cache['BOARD_DIR']) / 'board.cmake'
+        else:
+            board_cmake = 'board.cmake'
+        log.err(f'board {board} does not support runner {runner}',
+                fatal=True)
+        log.inf(f'To fix, configure this runner in {board_cmake} and rebuild.')
+        sys.exit(1)
     runner_cls = get_runner_cls(runner)
     if command.name not in runner_cls.capabilities().commands:
         log.die(f'runner {runner} does not support command {command.name}')