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

     1  package utils
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  )
     8  
     9  // The error is a wrapper for the.
    10  type (
    11  	SourceError struct {
    12  		SourceType               string   // The type of source that failed to build.
    13  		Title, Path, Description string   // Description of the error, as presented to the user.
    14  		Line, Column             int      // Where the error was encountered.
    15  		SourceLines              []string // The entire source file, split into lines.
    16  		Stack                    string   // The raw stack trace string from debug.Stack().
    17  		MetaError                string   // Error that occurred producing the error page.
    18  		Link                     string   // A configurable link to wrap the error source in
    19  	}
    20  	SourceLine struct {
    21  		Source  string
    22  		Line    int
    23  		IsError bool
    24  	}
    25  )
    26  
    27  // Return a new error object.
    28  func NewError(source, title, path, description string) *SourceError {
    29  	return &SourceError{
    30  		SourceType:  source,
    31  		Title:       title,
    32  		Path:        path,
    33  		Description: description,
    34  	}
    35  }
    36  
    37  // Creates a link based on the configuration setting "errors.link".
    38  func (e *SourceError) SetLink(errorLink string) {
    39  	errorLink = strings.ReplaceAll(errorLink, "{{Path}}", e.Path)
    40  	errorLink = strings.ReplaceAll(errorLink, "{{Line}}", strconv.Itoa(e.Line))
    41  
    42  	e.Link = "<a href=" + errorLink + ">" + e.Path + ":" + strconv.Itoa(e.Line) + "</a>"
    43  }
    44  
    45  // Error method constructs a plaintext version of the error, taking
    46  // account that fields are optionally set. Returns e.g. Compilation Error
    47  // (in views/header.html:51): expected right delim in end; got "}".
    48  func (e *SourceError) Error() string {
    49  	if e == nil {
    50  		panic("opps")
    51  	}
    52  	loc := ""
    53  	if e.Path != "" {
    54  		line := ""
    55  		if e.Line != 0 {
    56  			line = fmt.Sprintf(":%d", e.Line)
    57  		}
    58  		loc = fmt.Sprintf("(in %s%s)", e.Path, line)
    59  	}
    60  	header := loc
    61  	if e.Title != "" {
    62  		if loc != "" {
    63  			header = fmt.Sprintf("%s %s: ", e.Title, loc)
    64  		} else {
    65  			header = fmt.Sprintf("%s: ", e.Title)
    66  		}
    67  	}
    68  	return fmt.Sprintf("%s%s", header, e.Description)
    69  }
    70  
    71  // ContextSource method returns a snippet of the source around
    72  // where the error occurred.
    73  func (e *SourceError) ContextSource() []SourceLine {
    74  	if e.SourceLines == nil {
    75  		return nil
    76  	}
    77  	start := (e.Line - 1) - 5
    78  	if start < 0 {
    79  		start = 0
    80  	}
    81  	end := (e.Line - 1) + 5
    82  	if end > len(e.SourceLines) {
    83  		end = len(e.SourceLines)
    84  	}
    85  
    86  	lines := make([]SourceLine, end-start)
    87  	for i, src := range e.SourceLines[start:end] {
    88  		fileLine := start + i + 1
    89  		lines[i] = SourceLine{src, fileLine, fileLine == e.Line}
    90  	}
    91  	return lines
    92  }