Skip to content

Commit a0cb744

Browse files
committed
Merge pull request #475 from dsyme/fix-469
address 469 - capture proper FSharpErrorInfo and exceptions from evaluation
2 parents 01721a1 + 59102dc commit a0cb744

File tree

11 files changed

+364
-140
lines changed

11 files changed

+364
-140
lines changed

docs/content/interactive.fsx

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ First, we need to reference the libraries that contain F# interactive service:
3131
*)
3232

3333
#r "FSharp.Compiler.Service.dll"
34+
open Microsoft.FSharp.Compiler.SourceCodeServices
3435
open Microsoft.FSharp.Compiler.Interactive.Shell
3536

3637
(**
@@ -81,7 +82,7 @@ and other top-level statements.
8182
let evalInteraction text =
8283
fsiSession.EvalInteraction(text)
8384
(**
84-
The two functions take string as an argument and evaluate (or execute) it as F# code. The code
85+
The two functions each take a string as an argument and evaluate (or execute) it as F# code. The code
8586
passed to them does not require `;;` at the end. Just enter the code that you want to execute:
8687
*)
8788
evalExpression "42+1"
@@ -97,6 +98,49 @@ let evalScript scriptPath =
9798
File.WriteAllText("sample.fsx", "let twenty = 10 + 10")
9899
evalScript "sample.fsx"
99100

101+
(**
102+
Catching errors
103+
------------------
104+
105+
``EvalExpression``, ``EvalInteraction`` and ``EvalScript`` are awkward if the
106+
code has type checking warnings or errors, or if evaluation fails with an exception.
107+
In these cases you can use ``EvalExpressionNonThrowing``, ``EvalInteractionNonThrowing``
108+
and ``EvalScriptNonThrowing``. These return a tuple of a result and an array of ``FSharpErrorInfo`` values.
109+
These represent the errors and warnings. The result part is a ``Choice<_,_>`` between an actual
110+
result and an exception.
111+
112+
The result part of ``EvalExpression`` and ``EvalExpressionNonThrowing`` is an optional ``FSharpValue``.
113+
If that value is not present then it just indicates that the expression didn't have a tangible
114+
result that could be represented as a .NET object. This siutation shouldn't actually
115+
occur for any normal input expressions, and only for primitives used in libraries.
116+
*)
117+
118+
File.WriteAllText("sample.fsx", "let twenty = 'a' + 10.0")
119+
let result, warnings = fsiSession.EvalScriptNonThrowing "sample.fsx"
120+
121+
// show the result
122+
match result with
123+
| Choice1Of2 () -> printfn "checked and executed ok"
124+
| Choice2Of2 exn -> printfn "execution exception: %s" exn.Message
125+
126+
(**
127+
Gives:
128+
129+
execution exception: Operation could not be completed due to earlier error
130+
*)
131+
132+
// show the errors and warnings
133+
for w in warnings do
134+
printfn "Warning %s at %d,%d" w.Message w.StartLineAlternate w.StartColumn
135+
136+
(**
137+
Gives:
138+
139+
Warning The type 'float' does not match the type 'char' at 1,19
140+
Warning The type 'float' does not match the type 'char' at 1,17
141+
*)
142+
143+
100144
(**
101145
Type checking in the evaluation context
102146
------------------
@@ -129,8 +173,8 @@ You can also request declaration list information, tooltip text and symbol resol
129173
*)
130174
open Microsoft.FSharp.Compiler
131175

132-
let identToken = Parser.tagOfToken(Parser.token.IDENT(""))
133-
checkResults.GetToolTipTextAlternate(1, 2, "xxx + xx", ["xxx"], identToken) // a tooltip
176+
// get a tooltip
177+
checkResults.GetToolTipTextAlternate(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT)
134178

135179
checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // symbol xxx
136180

src/fsharp/ErrorLogger.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ let rec findOriginalException err =
3838

3939

4040
/// Thrown when we stop processing the F# Interactive entry or #load.
41-
exception StopProcessing of string
41+
exception StopProcessing of exn option
4242

4343

4444
(* common error kinds *)

src/fsharp/fsc.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2099,7 +2099,7 @@ type InProcCompiler() =
20992099
let exitCode = ref 0
21002100
let exiter =
21012101
{ new Exiter with
2102-
member this.Exit n = exitCode := n; raise (StopProcessing "") }
2102+
member this.Exit n = exitCode := n; raise (StopProcessing None) }
21032103
try
21042104
typecheckAndCompile(argv, false, true, exiter, loggerProvider, None, None)
21052105
with

0 commit comments

Comments
 (0)