github.com/wiselike/revel-cmd@v1.2.1/utils/build_error.go (about)

     1  package utils
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"regexp"
     7  	"strconv"
     8  
     9  	"github.com/wiselike/revel-cmd/logger"
    10  )
    11  
    12  type (
    13  	BuildError struct {
    14  		Stack   interface{}
    15  		Message string
    16  		Args    []interface{}
    17  	}
    18  )
    19  
    20  // Returns a new builed error.
    21  func NewBuildError(message string, args ...interface{}) (b *BuildError) {
    22  	Logger.Info(message, args...)
    23  	b = &BuildError{}
    24  	b.Message = message
    25  	b.Args = args
    26  	b.Stack = logger.NewCallStack()
    27  	Logger.Info("Stack", "stack", b.Stack)
    28  	return b
    29  }
    30  
    31  // Returns a new BuildError if err is not nil.
    32  func NewBuildIfError(err error, message string, args ...interface{}) (b error) {
    33  	if err != nil {
    34  		var berr *BuildError
    35  		if errors.As(err, &berr) {
    36  			// This is already a build error so just append the args
    37  			berr.Args = append(berr.Args, args...)
    38  			return berr
    39  		}
    40  
    41  		args = append(args, "error", err.Error())
    42  		b = NewBuildError(message, args...)
    43  	}
    44  
    45  	return
    46  }
    47  
    48  // BuildError implements Error() string.
    49  func (b *BuildError) Error() string {
    50  	return fmt.Sprint(b.Message, b.Args)
    51  }
    52  
    53  // Parse the output of the "go build" command.
    54  // Return a detailed Error.
    55  func NewCompileError(importPath, errorLink string, err error) *SourceError {
    56  	// Get the stack from the error
    57  
    58  	errorMatch := regexp.MustCompile(`(?m)^([^:#]+):(\d+):(\d+:)? (.*)$`).
    59  		FindSubmatch([]byte(err.Error()))
    60  	if errorMatch == nil {
    61  		errorMatch = regexp.MustCompile(`(?m)^(.*?):(\d+):\s(.*?)$`).FindSubmatch([]byte(err.Error()))
    62  
    63  		if errorMatch == nil {
    64  			Logger.Error("Failed to parse build errors", "error", err)
    65  			return &SourceError{
    66  				SourceType:  "Go code",
    67  				Title:       "Go Compilation Error",
    68  				Description: "See console for build error.",
    69  			}
    70  		}
    71  
    72  		errorMatch = append(errorMatch, errorMatch[3])
    73  
    74  		Logger.Error("Build errors", "errors", err)
    75  	}
    76  
    77  	// Read the source for the offending file.
    78  	var (
    79  		relFilename  = string(errorMatch[1]) // e.g. "src/revel/sample/app/controllers/app.go"
    80  		absFilename  = relFilename
    81  		line, _      = strconv.Atoi(string(errorMatch[2]))
    82  		description  = string(errorMatch[4])
    83  		compileError = &SourceError{
    84  			SourceType:  "Go code",
    85  			Title:       "Go Compilation Error",
    86  			Path:        relFilename,
    87  			Description: description,
    88  			Line:        line,
    89  		}
    90  	)
    91  
    92  	// errorLink := paths.Config.StringDefault("error.link", "")
    93  
    94  	if errorLink != "" {
    95  		compileError.SetLink(errorLink)
    96  	}
    97  
    98  	fileStr, err := ReadLines(absFilename)
    99  	if err != nil {
   100  		compileError.MetaError = absFilename + ": " + err.Error()
   101  		Logger.Info("Unable to readlines "+compileError.MetaError, "error", err)
   102  		return compileError
   103  	}
   104  
   105  	compileError.SourceLines = fileStr
   106  	return compileError
   107  }