MLstate / opalang

The Opa Language for Web Application Development
http://opalang.org
Other
1.24k stars 125 forks source link

A parse error is not exact #170

Closed Shiroy closed 9 years ago

Shiroy commented 9 years ago

During my implementation of Birdy following the book, I encountered this error :

Error: File "src/model/user.opa", line 96, characters 3-3, (96:3-96:3 | 2352-2352)
Parse error
  The error may be in the following citation, usually in the red part
  (starting at ⚐) or just before:

}
    }

    exposed function outcome(User.t, string) login(username, passwd)
    {
        x⚐ = ?/birdy/users[{username: username}]

        match(x){
            case {none}: {failure: "This user does not exist."}
            case {some: user}:

Hint:
  expected a returned expression at the end of the block, but found a binding. Did you mean `==' rather than `=' ?

But this code is correct.

The problem was due to this line of code I mistype :

if(user.passwd = passwd) 

Which should be

if(user.passwd == passwd)

The function is the same than in the book.

The error reporting should be improved because this report was not exact at all.

PS : I work with the last version of OPA compiled for Linux.

The wrong code

exposed function outcome(User.t, string) login(username, passwd)
    {
        x = ?/birdy/users[{username: username}]

        match(x){
            case {none}: {failure: "This user does not exist."}
            case {some: user}:
                match(user.status)
                {
                    case {activation_code: _}:
                        {failure: "This account is not activated."}                 
                    case {active} :
                        if(user.passwd = passwd)
                        {
                            user_view = mk_view(user)
                            UserContext.set(logged_user, {user: user_view})
                            {success: user_view}                        
                        }
                        else
                        {
                            {failure: "Incorrect password. Try again ;)"}
                        }
                }               
        }
    }

The correct one

exposed function outcome(User.t, string) login(username, passwd)
    {
        x = ?/birdy/users[{username: username}]

        match(x){
            case {none}: {failure: "This user does not exist."}
            case {some: user}:
                match(user.status)
                {
                    case {activation_code: _}:
                        {failure: "This account is not activated."}                 
                    case {active} :
                        if(user.passwd == passwd)
                        {
                            user_view = mk_view(user)
                            UserContext.set(logged_user, {user: user_view})
                            {success: user_view}                        
                        }
                        else
                        {
                            {failure: "Incorrect password. Try again ;)"}
                        }
                }               
        }
    }
HenriChataing commented 9 years ago

The scope of the syntax error is generally too large (for example, it will return the entire block if only one binding has a typo). You can try improving the precision by commenting out the bindings one by one.

Also, be careful of the following pitfall: subsequent xhtml values will always be concatenated, which causes the following code to fail (with expected a returned expression at the end of the block, but ...):

xhtml = <div>Some xhtml value</div>
<div id="container">
  {xhtml}
</div>
Shiroy commented 9 years ago

Yes, that's what I did to find the mistake in the if.

Thanks for the tip :)