Skip to content

Commit d1ede81

Browse files
authored
fix JSON decoding of ConversionResult in playground (#1073)
* catch errors when dynamically loading Playground component * load from prod CDN in dev * fix decoding of converson result * flatten some decode pattern matchings
1 parent 0c0e0c5 commit d1ede81

File tree

4 files changed

+55
-59
lines changed

4 files changed

+55
-59
lines changed

src/Try.res

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ let default = props => {
44
let (isOverlayOpen, setOverlayOpen) = React.useState(() => false)
55

66
let lazyPlayground = Next.Dynamic.dynamic(
7-
async () => await import(Playground.make),
7+
async () => {
8+
try {
9+
await import(Playground.make)
10+
} catch {
11+
| JsExn(e) =>
12+
Console.error2("Error loading Playground:", e)
13+
JsExn.throw(e)
14+
}
15+
},
816
{
917
ssr: false,
1018
loading: () => <span> {React.string("Loading...")} </span>,

src/bindings/Node.res

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ module Process = {
1616
@scope("process") external env: Dict.t<string> = "env"
1717
@scope("process") @val external argv: array<string> = "argv"
1818
@scope("process") external exit: int => unit = "exit"
19+
module Env = {
20+
@scope(("process", "env")) external nodeEnv: string = "NODE_ENV"
21+
}
1922
}
2023

2124
module Fs = {

src/bindings/RescriptCompilerApi.res

Lines changed: 39 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -317,39 +317,29 @@ module CompileFail = {
317317
let decode = (json): t => {
318318
open JSON
319319
switch json {
320-
| Object(dict{"type": String(type_)}) =>
321-
switch type_ {
322-
| "syntax_error" =>
323-
let locMsgs = switch json {
324-
| Object(dict{"errors": Array(errors)}) => errors->Array.map(LocMsg.decode)
325-
| _ => throw(Failure(`Failed to decode errors from syntax_error. ${__LOC__}`))
326-
}
327-
// TODO: There seems to be a bug in the ReScript bundle that reports
328-
// back multiple LocMsgs of the same value
329-
locMsgs->LocMsg.dedupe->SyntaxErr
330-
| "type_error" =>
331-
let locMsgs = switch json {
332-
| Object(dict{"errors": Array(errors)}) => errors->Array.map(LocMsg.decode)
333-
| _ => throw(Failure(`Failed to decode errors from type_error. ${__LOC__}`))
334-
}
335-
TypecheckErr(locMsgs)
336-
| "warning_error" =>
337-
let warnings = switch json {
338-
| Object(dict{"errors": Array(warnings)}) => warnings->Array.map(Warning.decode)
339-
| _ => throw(Failure(`Failed to decode errors from warning_error. ${__LOC__}`))
340-
}
341-
WarningErr(warnings)
342-
| "other_error" =>
343-
let locMsgs = switch json {
344-
| Object(dict{"errors": Array(errors)}) => errors->Array.map(LocMsg.decode)
345-
| _ => throw(Failure(`Failed to decode errors from other_error. ${__LOC__}`))
346-
}
347-
OtherErr(locMsgs)
348-
349-
| "warning_flag_error" => WarningFlagErr(WarningFlag.decode(json))
350-
| other => throw(Failure(`Unknown type "${other}" in CompileFail result. ${__LOC__}`))
351-
}
352-
| _ => throw(Failure(`Failed to decode CompileFail. ${__LOC__}`))
320+
| Object(dict{"type": String("syntax_error"), "errors": Array(errors)}) =>
321+
let locMsgs = errors->Array.map(LocMsg.decode)
322+
// TODO: There seems to be a bug in the ReScript bundle that reports
323+
// back multiple LocMsgs of the same value
324+
locMsgs->LocMsg.dedupe->SyntaxErr
325+
| Object(dict{"type": String("type_error"), "errors": Array(errors)}) =>
326+
let locMsgs = errors->Array.map(LocMsg.decode)
327+
TypecheckErr(locMsgs)
328+
| Object(dict{"type": String("warning_error"), "errors": Array(warnings)}) =>
329+
let warnings = warnings->Array.map(Warning.decode)
330+
WarningErr(warnings)
331+
| Object(dict{"type": String("other_error"), "errors": Array(errors)}) =>
332+
let locMsgs = errors->Array.map(LocMsg.decode)
333+
OtherErr(locMsgs)
334+
| Object(dict{"type": String("warning_flag_error")}) => WarningFlagErr(WarningFlag.decode(json))
335+
| Object(dict{"type": String(other)}) =>
336+
throw(Failure(`Unknown type "${other}" in CompileFail result. ${__LOC__}`))
337+
| _ =>
338+
throw(
339+
Failure(
340+
`Failed to decode CompileFail. ${__LOC__}. Could not decode \`${json->JSON.stringify}\``,
341+
),
342+
)
353343
}
354344
}
355345
}
@@ -365,16 +355,9 @@ module CompilationResult = {
365355
let decode = (~time: float, json: JSON.t): t => {
366356
open JSON
367357
switch json {
368-
| Object(dict{"type": String(type_)}) =>
369-
switch type_ {
370-
| "success" => Success(CompileSuccess.decode(~time, json))
371-
| "unexpected_error" =>
372-
switch json {
373-
| Object(dict{"msg": String(msg)}) => UnexpectedError(msg)
374-
| _ => throw(Failure(`Failed to decode msg from unexpected_error. ${__LOC__}`))
375-
}
376-
| _ => Fail(CompileFail.decode(json))
377-
}
358+
| Object(dict{"type": String("success")}) => Success(CompileSuccess.decode(~time, json))
359+
| Object(dict{"type": String("unexpected_error"), "msg": String(msg)}) => UnexpectedError(msg)
360+
| Object(dict{"type": String(_)}) => Fail(CompileFail.decode(json))
378361
| _ => throw(Failure(`Failed to decode CompilationResult. ${__LOC__}`))
379362
}
380363
}
@@ -390,20 +373,19 @@ module ConversionResult = {
390373
let decode = (~fromLang: Lang.t, ~toLang: Lang.t, json): t => {
391374
open JSON
392375
switch json {
393-
| Object(dict{
394-
"type": String(type_),
395-
"msg": ?Some(String(msg)),
396-
"errors": ?Some(Array(errors)),
397-
}) =>
398-
switch type_ {
399-
| "success" => Success(ConvertSuccess.decode(json))
400-
| "unexpected_error" => msg->UnexpectedError
401-
| "syntax_error" =>
402-
let locMsgs = errors->Array.map(LocMsg.decode)
403-
Fail({fromLang, toLang, details: locMsgs})
404-
| other => Unknown(`Unknown conversion result type "${other}"`, json)
405-
}
406-
| _ => throw(Failure(`Failed to decode ConversionResult. ${__LOC__}`))
376+
| Object(dict{"type": String("success")}) => Success(ConvertSuccess.decode(json))
377+
| Object(dict{"type": String("unexpected_error"), "msg": String(msg)}) => UnexpectedError(msg)
378+
| Object(dict{"type": String("syntax_error"), "errors": Array(errors)}) =>
379+
let locMsgs = errors->Array.map(LocMsg.decode)
380+
Fail({fromLang, toLang, details: locMsgs})
381+
| Object(dict{"type": String(other)}) =>
382+
Unknown(`Unknown conversion result type "${other}"`, json)
383+
| _ =>
384+
throw(
385+
Failure(
386+
`Failed to decode ConversionResult. ${__LOC__}. Could not decode \`${json->JSON.stringify}\``,
387+
),
388+
)
407389
}
408390
}
409391
}

src/common/CompilerManagerHook.res

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ module LoadScript = {
3535
}
3636

3737
module CdnMeta = {
38-
let baseUrl = "/playground-bundles"
38+
let baseUrl =
39+
Node.Process.Env.nodeEnv === "development"
40+
? "https://cdn.rescript-lang.org"
41+
: "" + "/playground-bundles"
3942

4043
let getCompilerUrl = (version): string => `${baseUrl}/${Semver.toString(version)}/compiler.js`
4144

0 commit comments

Comments
 (0)