Skip to content

Commit

Permalink
Fix(transformer/elm): handle elm error
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinyaigeek committed Jul 18, 2022
1 parent a9193ce commit 7f918ba
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 14 deletions.
43 changes: 43 additions & 0 deletions packages/core/integration-tests/test/elm.js
Expand Up @@ -133,4 +133,47 @@ describe('elm', function () {
},
);
});

it('should produce correct formatting and indentation when elm fails without errors property', async function () {
await assert.rejects(
() =>
bundle(path.join(__dirname, 'integration/elm-error/index.js'), {
mode: 'production',
}),

{
name: 'BuildError',
diagnostics: [
{
message:
'\n' +
'-- DEBUG REMNANTS ------------------------------------------------------------- \n' +
'\n' +
'There are uses of the `Debug` module in the following modules:\n' +
'\n' +
' **Main**\n' +
'\n' +
'But the --optimize flag only works if all `Debug` functions are removed!\n' +
'\n' +
'__Note__: The issue is that --optimize strips out info needed by `Debug` functions.\n' +
'Here are two examples:\n' +
'\n' +
' (1) It shortens record field names. This makes the generated JavaScript is\n' +
' smaller, but `Debug.toString` cannot know the real field names anymore.\n' +
'\n' +
' (2) Values like `type Height = Height Float` are unboxed. This reduces\n' +
' allocation, but it also means that `Debug.toString` cannot tell if it is\n' +
' looking at a `Height` or `Float` value.\n' +
'\n' +
'There are a few other cases like that, and it will be much worse once we start\n' +
'inlining code. That optimization could move `Debug.log` and `Debug.todo` calls,\n' +
'resulting in unpredictable behavior. I hope that clarifies why this restriction\n' +
'exists!',
origin: '@parcel/elm-transformer',
stack: '',
},
],
},
);
});
});
@@ -0,0 +1,24 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}
@@ -0,0 +1,5 @@
var local = require('./src/Main.elm');

module.exports = function () {
return local;
};
@@ -0,0 +1 @@
{}
@@ -0,0 +1,49 @@
module Main exposing (main)

import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)


type alias Model =
{ count : Int }


initialModel : Model
initialModel =
{ count = 0 }


type Msg
= Increment
| Decrement


update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
Debug.log "incremented!!"
{ model | count = model.count + 1 }

Decrement ->
Debug.log "decremented!!"
{ model | count = model.count - 1 }


view : Model -> Html Msg
view model =
div []
[ button [ onClick Increment ] [ text "+1" ]
, div [] [ text <| String.fromInt model.count ]
, button [ onClick Decrement ] [ text "-1" ]
]


main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, view = view
, update = update
}
Empty file.
46 changes: 32 additions & 14 deletions packages/transformers/elm/src/ElmTransformer.js
Expand Up @@ -64,6 +64,20 @@ export default (new Transformer({
let compilerJson = e.message.split('\n')[1];
let compilerDiagnostics = JSON.parse(compilerJson);

// sometimes, `errors` property does not exist on the error object thrown by `compileToString` module.
// In such case, a content equal to `error.errors[num].problems[num]` is expanded.
// so this line handle such a case.
if (!compilerDiagnostics.errors) {
throw new ThrowableDiagnostic({
diagnostic: elmProblemToParcelDiagnostic(
compilerDiagnostics,
compilerDiagnostics.path
? path.relative(process.cwd(), compilerDiagnostics.path)
: '',
),
});
}

throw new ThrowableDiagnostic({
diagnostic: compilerDiagnostics.errors.flatMap(
elmErrorToParcelDiagnostics,
Expand Down Expand Up @@ -173,22 +187,26 @@ function formatMessagePiece(piece) {
return md`${piece}`;
}

function elmProblemToParcelDiagnostic(problem, relativePath) {
const padLength = 80 - 5 - problem.title.length - relativePath.length;
const dashes = '-'.repeat(padLength);
const message = [
'',
`-- ${problem.title} ${dashes} ${relativePath}`,
'',
problem.message.map(formatMessagePiece).join(''),
].join('\n');

return {
message,
origin: '@parcel/elm-transformer',
stack: '', // set stack to empty since it is not useful
};
}

function elmErrorToParcelDiagnostics(error) {
const relativePath = path.relative(process.cwd(), error.path);
return error.problems.map(problem => {
const padLength = 80 - 5 - problem.title.length - relativePath.length;
const dashes = '-'.repeat(padLength);
const message = [
'',
`-- ${problem.title} ${dashes} ${relativePath}`,
'',
problem.message.map(formatMessagePiece).join(''),
].join('\n');

return {
message,
origin: '@parcel/elm-transformer',
stack: '', // set stack to empty since it is not useful
};
return elmProblemToParcelDiagnostic(problem, relativePath);
});
}

0 comments on commit 7f918ba

Please sign in to comment.