提交 0dc21fae 编写于 作者: B Brett V. Forsgren 提交者: Kevin Ransom (msft)

create a specific exception type to represent FSI compilation errors (#7713)

上级 10373fd7
......@@ -52,3 +52,5 @@ fsiBindingSessionTo,"Binding session to '%s'..."
fsiProductName,"Microsoft (R) F# Interactive version %s"
fsiProductNameCommunity,"F# Interactive for F# %s"
shadowCopyReferences,"Prevents references from being locked by the F# Interactive process"
fsiOperationCouldNotBeCompleted,"Operation could not be completed due to earlier error"
fsiOperationFailed,"Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing"
......@@ -2280,6 +2280,11 @@ let internal DriveFsiEventLoop (fsi: FsiEvaluationSessionHostConfig, fsiConsoleO
runLoop();
/// Thrown when there was an error compiling the given code in FSI.
type FsiCompilationException(message: string, errorInfos: FSharpErrorInfo[] option) =
inherit System.Exception(message)
member __.ErrorInfos = errorInfos
/// The primary type, representing a full F# Interactive session, reading from the given
/// text input, writing to the given text output and error writers.
type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], inReader:TextReader, outWriter:TextWriter, errorWriter: TextWriter, fsiCollectible: bool, legacyReferenceResolver: ReferenceResolver.Resolver option) =
......@@ -2443,21 +2448,22 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i
let fsiInteractionProcessor = FsiInteractionProcessor(fsi, tcConfigB, fsiOptions, fsiDynamicCompiler, fsiConsolePrompt, fsiConsoleOutput, fsiInterruptController, fsiStdinLexerProvider, lexResourceManager, initialInteractiveState)
let commitResult res =
match res with
match res with
| Choice1Of2 r -> r
| Choice2Of2 None -> failwith "Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing"
| Choice2Of2 None -> raise (FsiCompilationException(FSIstrings.SR.fsiOperationFailed(), None))
| Choice2Of2 (Some userExn) -> raise userExn
let commitResultNonThrowing errorOptions scriptFile (errorLogger: CompilationErrorLogger) res =
let commitResultNonThrowing errorOptions scriptFile (errorLogger: CompilationErrorLogger) res =
let errs = errorLogger.GetErrors()
let userRes =
match res with
let errorInfos = ErrorHelpers.CreateErrorInfos (errorOptions, true, scriptFile, errs, true)
let userRes =
match res with
| Choice1Of2 r -> Choice1Of2 r
| Choice2Of2 None -> Choice2Of2 (System.Exception "Operation could not be completed due to earlier error")
| Choice2Of2 None -> Choice2Of2 (FsiCompilationException(FSIstrings.SR.fsiOperationCouldNotBeCompleted(), Some errorInfos) :> exn)
| Choice2Of2 (Some userExn) -> Choice2Of2 userExn
// 'true' is passed for "suggestNames" because we want the FSI session to suggest names for misspellings and it won't affect IDE perf much
userRes, ErrorHelpers.CreateErrorInfos (errorOptions, true, scriptFile, errs, true)
userRes, errorInfos
let dummyScriptFileName = "input.fsx"
......
......@@ -106,6 +106,12 @@ type public FsiEvaluationSessionHostConfig =
/// Implicitly reference FSharp.Compiler.Interactive.Settings.dll
abstract UseFsiAuxLib : bool
/// Thrown when there was an error compiling the given code in FSI.
[<Class>]
type FsiCompilationException =
inherit System.Exception
new : string * FSharpErrorInfo[] option -> FsiCompilationException
member ErrorInfos : FSharpErrorInfo[] option
/// Represents an F# Interactive evaluation session.
[<Class>]
......@@ -184,7 +190,7 @@ type FsiEvaluationSession =
///
/// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered
/// by input from 'stdin'.
member EvalExpressionNonThrowing : code: string -> Choice<FsiValue option, exn> * FSharpErrorInfo[]
member EvalExpressionNonThrowing : code: string -> Choice<FsiValue option, exn> * FSharpErrorInfo[]
/// Format a value to a string using the current PrintDepth, PrintLength etc settings provided by the active fsi configuration object
member FormatValue : reflectionValue: obj * reflectionType: System.Type -> string
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="cs" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Zastavilo se kvůli chybě.\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="de" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Aufgrund eines Fehlers beendet\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="es" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Detenido debido a un error.\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="fr" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Arrêt en raison d'une erreur\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="it" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Interruzione a causa di un errore\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="ja" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">エラーのため停止しました\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="ko" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">오류 때문에 중지되었습니다.\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="pl" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Zatrzymano ze względu na błąd\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="pt-BR" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Interrompido devido a erro\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="ru" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Остановлено из-за ошибки\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="tr" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">Hata nedeniyle durduruldu\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="zh-Hans" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">已因出错而停止\n</target>
......
......@@ -2,6 +2,16 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="zh-Hant" original="../FSIstrings.resx">
<body>
<trans-unit id="fsiOperationCouldNotBeCompleted">
<source>Operation could not be completed due to earlier error</source>
<target state="new">Operation could not be completed due to earlier error</target>
<note />
</trans-unit>
<trans-unit id="fsiOperationFailed">
<source>Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</source>
<target state="new">Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing</target>
<note />
</trans-unit>
<trans-unit id="stoppedDueToError">
<source>Stopped due to error\n</source>
<target state="translated">已因錯誤而停止\n</target>
......
......@@ -90,3 +90,20 @@ type InteractiveTests() =
let _result, errors = script.Eval(sprintf "#r \"%s\"" testAssembly)
Assert.AreEqual(1, errors.Length)
Assert.False(foundAssemblyReference)
[<Test>]
member _.``Compilation errors report a specific exception``() =
use script = new FSharpScript()
let result, _errors = script.Eval("abc")
match result with
| Ok(_) -> Assert.Fail("expected a failure")
| Error(ex) -> Assert.IsInstanceOf<FsiCompilationException>(ex)
[<Test>]
member _.``Runtime exceptions are propagated``() =
use script = new FSharpScript()
let result, errors = script.Eval("System.IO.File.ReadAllText(\"not-a-file-path-that-can-be-found-on-disk.txt\")")
Assert.IsEmpty(errors)
match result with
| Ok(_) -> Assert.Fail("expected a failure")
| Error(ex) -> Assert.IsInstanceOf<FileNotFoundException>(ex)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册