Skip to content

Commit 7fd3182

Browse files
committed
Handle non-string return values from the user's prompt function
This change adds a catch for the InvalidCastException when gathering the user's prompt string in the case where their prompt function returns a value other than a string. In this case a default prompt is returned. This change also improves the way we write prompts for the debugger. Instead of writing out the prompt each time the debugger stops, we write out the details about the breakpoint that was hit, if any. We also try to preserve any session context at the beginning of the prompt string like the remote computer name or process ID. Fixes #339.
1 parent a878a99 commit 7fd3182

File tree

1 file changed

+66
-10
lines changed

1 file changed

+66
-10
lines changed

src/PowerShellEditorServices/Session/PowerShellContext.cs

+66-10
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ private void SetExecutionPolicy(ExecutionPolicy desiredExecutionPolicy)
12121212
}
12131213
}
12141214

1215-
private void WritePromptToHost(Func<PSCommand, string> invokeAction)
1215+
private string GetPromptString(Func<PSCommand, string> invokeAction)
12161216
{
12171217
string promptString = null;
12181218

@@ -1228,26 +1228,42 @@ private void WritePromptToHost(Func<PSCommand, string> invokeAction)
12281228
LogLevel.Verbose,
12291229
"Runtime exception occurred while executing prompt command:\r\n\r\n" + e.ToString());
12301230
}
1231+
catch (InvalidCastException e)
1232+
{
1233+
Logger.WriteException(
1234+
LogLevel.Verbose,
1235+
"Prompt function returned a result which is not a string.",
1236+
e);
1237+
}
12311238
finally
12321239
{
1233-
promptString = promptString ?? "PS >";
1240+
promptString = promptString ?? "PS>";
12341241
}
12351242

1236-
this.WriteOutput(
1237-
Environment.NewLine,
1238-
false);
1239-
12401243
// Trim the '>' off the end of the prompt string to reduce
12411244
// user confusion about where they can type.
12421245
// TODO: Eventually put this behind a setting, #133
1243-
promptString = promptString.TrimEnd(' ', '>', '\r', '\n');
1246+
return promptString.TrimEnd(' ', '>', '\r', '\n');
1247+
}
1248+
1249+
private void WritePromptStringToHost(string promptString)
1250+
{
1251+
this.WriteOutput(
1252+
Environment.NewLine,
1253+
false);
12441254

12451255
// Write the prompt string
12461256
this.WriteOutput(
12471257
promptString,
12481258
true);
12491259
}
12501260

1261+
private void WritePromptToHost(Func<PSCommand, string> invokeAction)
1262+
{
1263+
this.WritePromptStringToHost(
1264+
this.GetPromptString(invokeAction));
1265+
}
1266+
12511267
private void WritePromptWithRunspace(Runspace runspace)
12521268
{
12531269
this.WritePromptToHost(
@@ -1275,9 +1291,9 @@ private void WritePromptWithRunspace(Runspace runspace)
12751291
});
12761292
}
12771293

1278-
private void WritePromptInDebugger()
1294+
private string GetPromptInDebugger()
12791295
{
1280-
this.WritePromptToHost(
1296+
return this.GetPromptString(
12811297
command =>
12821298
{
12831299
return
@@ -1286,6 +1302,46 @@ private void WritePromptInDebugger()
12861302
});
12871303
}
12881304

1305+
private void WritePromptInDebugger(DebuggerStopEventArgs eventArgs = null)
1306+
{
1307+
string promptPrefix = string.Empty;
1308+
string promptString = this.GetPromptInDebugger();
1309+
1310+
if (eventArgs != null)
1311+
{
1312+
// Is there a prompt prefix worth keeping?
1313+
const string promptSeparator = "]: ";
1314+
if (promptString != null && promptString[0] == ('['))
1315+
{
1316+
int separatorIndex = promptString.LastIndexOf(promptSeparator);
1317+
if (separatorIndex > 0)
1318+
{
1319+
promptPrefix =
1320+
promptString.Substring(
1321+
0,
1322+
separatorIndex + promptSeparator.Length);
1323+
}
1324+
}
1325+
1326+
// This was called from OnDebuggerStop, write a different prompt
1327+
if (eventArgs.Breakpoints.Count > 0)
1328+
{
1329+
// The breakpoint classes have nice ToString output so use that
1330+
promptString = $"Hit {eventArgs.Breakpoints[0].ToString()}";
1331+
}
1332+
else
1333+
{
1334+
// TODO: What do we display when we don't know why we stopped?
1335+
promptString = null;
1336+
}
1337+
}
1338+
1339+
if (promptString != null)
1340+
{
1341+
this.WritePromptStringToHost(promptPrefix + promptString);
1342+
}
1343+
}
1344+
12891345
private void WritePromptWithNestedPipeline()
12901346
{
12911347
using (var pipeline = this.CurrentRunspace.Runspace.CreateNestedPipeline())
@@ -1418,7 +1474,7 @@ private void OnDebuggerStop(object sender, DebuggerStopEventArgs e)
14181474
}
14191475

14201476
// Write out the debugger prompt
1421-
this.WritePromptInDebugger();
1477+
this.WritePromptInDebugger(e);
14221478

14231479
// Raise the event for the debugger service
14241480
this.DebuggerStop?.Invoke(sender, e);

0 commit comments

Comments
 (0)