Skip to content

Commit e4c1ff0

Browse files
committed
Better handling of exception after exception
1 parent 6e68063 commit e4c1ff0

File tree

2 files changed

+69
-61
lines changed

2 files changed

+69
-61
lines changed

PSReadLine/ReadLine.cs

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -243,79 +243,87 @@ private bool BreakHandler(ConsoleBreakSignal signal)
243243
/// after the prompt has been displayed.
244244
/// </summary>
245245
/// <returns>The complete command line.</returns>
246-
public static string ReadLine(Runspace remoteRunspace = null, EngineIntrinsics engineIntrinsics = null)
246+
public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
247247
{
248248
var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Input);
249249
NativeMethods.GetConsoleMode(handle, out _singleton._prePSReadlineConsoleMode);
250-
try
251-
{
252-
// Clear a couple flags so we can actually receive certain keys:
253-
// ENABLE_PROCESSED_INPUT - enables Ctrl+C
254-
// ENABLE_LINE_INPUT - enables Ctrl+S
255-
// Also clear a couple flags so we don't mask the input that we ignore:
256-
// ENABLE_MOUSE_INPUT - mouse events
257-
// ENABLE_WINDOW_INPUT - window resize events
258-
var mode = _singleton._prePSReadlineConsoleMode &
259-
~(NativeMethods.ENABLE_PROCESSED_INPUT |
260-
NativeMethods.ENABLE_LINE_INPUT |
261-
NativeMethods.ENABLE_WINDOW_INPUT |
262-
NativeMethods.ENABLE_MOUSE_INPUT);
263-
NativeMethods.SetConsoleMode(handle, mode);
264-
265-
_singleton.Initialize(remoteRunspace, engineIntrinsics);
266-
return _singleton.InputLoop();
267-
}
268-
catch (OperationCanceledException)
269-
{
270-
// Console is exiting - return value isn't too critical - null or 'exit' could work equally well.
271-
return "";
272-
}
273-
catch (ExitException)
274-
{
275-
return "exit";
276-
}
277-
catch (Exception e)
250+
bool firstTime = true;
251+
while (true)
278252
{
279-
// If we're running tests, just throw.
280-
if (_singleton._mockableMethods != _singleton)
253+
try
281254
{
282-
throw;
283-
}
255+
// Clear a couple flags so we can actually receive certain keys:
256+
// ENABLE_PROCESSED_INPUT - enables Ctrl+C
257+
// ENABLE_LINE_INPUT - enables Ctrl+S
258+
// Also clear a couple flags so we don't mask the input that we ignore:
259+
// ENABLE_MOUSE_INPUT - mouse events
260+
// ENABLE_WINDOW_INPUT - window resize events
261+
var mode = _singleton._prePSReadlineConsoleMode &
262+
~(NativeMethods.ENABLE_PROCESSED_INPUT |
263+
NativeMethods.ENABLE_LINE_INPUT |
264+
NativeMethods.ENABLE_WINDOW_INPUT |
265+
NativeMethods.ENABLE_MOUSE_INPUT);
266+
NativeMethods.SetConsoleMode(handle, mode);
267+
268+
if (firstTime)
269+
{
270+
firstTime = false;
271+
_singleton.Initialize(runspace, engineIntrinsics);
272+
}
284273

285-
while (e.InnerException != null)
274+
return _singleton.InputLoop();
275+
}
276+
catch (OperationCanceledException)
277+
{
278+
// Console is exiting - return value isn't too critical - null or 'exit' could work equally well.
279+
return "";
280+
}
281+
catch (ExitException)
286282
{
287-
e = e.InnerException;
283+
return "exit";
288284
}
289-
var oldColor = Console.ForegroundColor;
290-
Console.ForegroundColor = ConsoleColor.Red;
291-
Console.WriteLine(PSReadLineResources.OopsAnErrorMessage1);
292-
Console.ForegroundColor = oldColor;
293-
var sb = new StringBuilder();
294-
for (int i = 0; i < _lastNKeys.Count; i++)
285+
catch (Exception e)
295286
{
296-
sb.Append(' ');
297-
sb.Append(_lastNKeys[i].ToGestureString());
287+
// If we're running tests, just throw.
288+
if (_singleton._mockableMethods != _singleton)
289+
{
290+
throw;
291+
}
298292

299-
KeyHandler handler;
300-
if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out handler) &&
301-
"AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase))
293+
while (e.InnerException != null)
302294
{
303-
// Make it a little easier to see the keys
304-
sb.Append('\n');
295+
e = e.InnerException;
305296
}
306-
// TODO: print non-default function bindings and script blocks
307-
}
297+
var oldColor = Console.ForegroundColor;
298+
Console.ForegroundColor = ConsoleColor.Red;
299+
Console.WriteLine(PSReadLineResources.OopsAnErrorMessage1);
300+
Console.ForegroundColor = oldColor;
301+
var sb = new StringBuilder();
302+
for (int i = 0; i < _lastNKeys.Count; i++)
303+
{
304+
sb.Append(' ');
305+
sb.Append(_lastNKeys[i].ToGestureString());
308306

309-
Console.WriteLine(PSReadLineResources.OopsAnErrorMessage2, _lastNKeys.Count, sb, e);
310-
var lineBeforeCrash = _singleton._buffer.ToString();
311-
_singleton.Initialize(remoteRunspace, _singleton._engineIntrinsics);
312-
InvokePrompt();
313-
Insert(lineBeforeCrash);
314-
return _singleton.InputLoop();
315-
}
316-
finally
317-
{
318-
NativeMethods.SetConsoleMode(handle, _singleton._prePSReadlineConsoleMode);
307+
KeyHandler handler;
308+
if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out handler) &&
309+
"AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase))
310+
{
311+
// Make it a little easier to see the keys
312+
sb.Append('\n');
313+
}
314+
// TODO: print non-default function bindings and script blocks
315+
}
316+
317+
Console.WriteLine(PSReadLineResources.OopsAnErrorMessage2, _lastNKeys.Count, sb, e);
318+
var lineBeforeCrash = _singleton._buffer.ToString();
319+
_singleton.Initialize(runspace, _singleton._engineIntrinsics);
320+
InvokePrompt();
321+
Insert(lineBeforeCrash);
322+
}
323+
finally
324+
{
325+
NativeMethods.SetConsoleMode(handle, _singleton._prePSReadlineConsoleMode);
326+
}
319327
}
320328
}
321329

UnitTestPSReadLine/UnitTestReadLine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ static private void Test(string expectedResult, object[] items, bool resetCursor
576576
.GetField("_mockableMethods", BindingFlags.Instance | BindingFlags.NonPublic)
577577
.SetValue(instance, mockedMethods);
578578

579-
var result = PSConsoleReadLine.ReadLine();
579+
var result = PSConsoleReadLine.ReadLine(null, null);
580580

581581
if (mockedMethods.validationFailure != null)
582582
{

0 commit comments

Comments
 (0)