OSDN Git Service

fix error response for compile contract (#1424)
authoroysheng <33340252+oysheng@users.noreply.github.com>
Thu, 25 Oct 2018 08:45:18 +0000 (16:45 +0800)
committerPaladz <yzhu101@uottawa.ca>
Thu, 25 Oct 2018 08:45:18 +0000 (16:45 +0800)
* fix error response for compile contract

* optimise

* fix excepted contract check

* optimise

api/compile.go
api/errors.go
equity/compiler/parse.go

index 32521e7..4a36bbe 100644 (file)
@@ -5,9 +5,16 @@ import (
 
        chainjson "github.com/bytom/encoding/json"
        "github.com/bytom/equity/compiler"
+       "github.com/bytom/errors"
        "github.com/bytom/protocol/vm"
 )
 
+// pre-define contract error types
+var (
+       ErrCompileContract = errors.New("compile contract failed")
+       ErrInstContract    = errors.New("instantiate contract failed")
+)
+
 type (
        compileReq struct {
                Contract string                 `json:"contract"`
@@ -26,17 +33,16 @@ type (
        }
 )
 
-func compileEquity(req compileReq) (compileResp, error) {
-       var resp compileResp
+func compileEquity(req compileReq) (*compileResp, error) {
        compiled, err := compiler.Compile(strings.NewReader(req.Contract))
        if err != nil {
-               resp.Error = err.Error()
+               return nil, errors.WithDetail(ErrCompileContract, err.Error())
        }
 
        // if source contract maybe contain import statement, multiple contract objects will be generated
        // after the compilation, and the last object is what we need.
        contract := compiled[len(compiled)-1]
-       resp compileResp{
+       resp := &compileResp{
                Name:    contract.Name,
                Source:  req.Contract,
                Program: contract.Body,
@@ -48,12 +54,12 @@ func compileEquity(req compileReq) (compileResp, error) {
        if req.Args != nil {
                resp.Program, err = compiler.Instantiate(contract.Body, contract.Params, contract.Recursive, req.Args)
                if err != nil {
-                       resp.Error = err.Error()
+                       return nil, errors.WithDetail(ErrInstContract, err.Error())
                }
 
                resp.Opcodes, err = vm.Disassemble(resp.Program)
                if err != nil {
-                       return resp, err
+                       return nil, err
                }
        }
 
@@ -73,5 +79,5 @@ func (a *API) compileEquity(req compileReq) Response {
        if err != nil {
                return NewErrorResponse(err)
        }
-       return NewSuccessResponse(resp)
+       return NewSuccessResponse(&resp)
 }
index 9b6bc65..c0ae2c9 100644 (file)
@@ -50,6 +50,10 @@ var respErrFormatter = map[error]httperror.Info{
        signers.ErrNoXPubs:   {400, "BTM202", "At least one xpub is required"},
        signers.ErrDupeXPub:  {400, "BTM203", "Root XPubs cannot contain the same key more than once"},
 
+       // Contract error namespace (3xx)
+       ErrCompileContract: {400, "BTM300", "Compile contract failed"},
+       ErrInstContract:    {400, "BTM301", "Instantiate contract failed"},
+
        // Transaction error namespace (7xx)
        // Build transaction error namespace (70x ~ 72x)
        account.ErrInsufficient:         {400, "BTM700", "Funds of account are insufficient"},
index 61a4765..7a29599 100644 (file)
@@ -48,6 +48,10 @@ func parse(buf []byte) (contracts []*Contract, err error) {
 
 func parseContracts(p *parser) []*Contract {
        var result []*Contract
+       if pos := scanKeyword(p.buf, p.pos, "contract"); pos < 0 {
+               p.errorf("expected contract")
+       }
+
        for peekKeyword(p) == "contract" {
                contract := parseContract(p)
                result = append(result, contract)