github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/flosch/pongo2.v3/error.go (about)

     1  package pongo2
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"os"
     7  )
     8  
     9  // This Error type is being used to address an error during lexing, parsing or
    10  // execution. If you want to return an error object (for example in your own
    11  // tag or filter) fill this object with as much information as you have.
    12  // Make sure "Sender" is always given (if you're returning an error within
    13  // a filter, make Sender equals 'filter:yourfilter'; same goes for tags: 'tag:mytag').
    14  // It's okay if you only fill in ErrorMsg if you don't have any other details at hand.
    15  type Error struct {
    16  	Template *Template
    17  	Filename string
    18  	Line     int
    19  	Column   int
    20  	Token    *Token
    21  	Sender   string
    22  	ErrorMsg string
    23  }
    24  
    25  func (e *Error) updateFromTokenIfNeeded(template *Template, t *Token) *Error {
    26  	if e.Template == nil {
    27  		e.Template = template
    28  	}
    29  
    30  	if e.Token == nil {
    31  		e.Token = t
    32  		if e.Line <= 0 {
    33  			e.Line = t.Line
    34  			e.Column = t.Col
    35  		}
    36  	}
    37  
    38  	return e
    39  }
    40  
    41  // Returns a nice formatted error string.
    42  func (e *Error) Error() string {
    43  	s := "[Error"
    44  	if e.Sender != "" {
    45  		s += " (where: " + e.Sender + ")"
    46  	}
    47  	if e.Filename != "" {
    48  		s += " in " + e.Filename
    49  	}
    50  	if e.Line > 0 {
    51  		s += fmt.Sprintf(" | Line %d Col %d", e.Line, e.Column)
    52  		if e.Token != nil {
    53  			s += fmt.Sprintf(" near '%s'", e.Token.Val)
    54  		}
    55  	}
    56  	s += "] "
    57  	s += e.ErrorMsg
    58  	return s
    59  }
    60  
    61  // Returns the affected line from the original template, if available.
    62  func (e *Error) RawLine() (line string, available bool) {
    63  	if e.Line <= 0 || e.Filename == "<string>" {
    64  		return "", false
    65  	}
    66  
    67  	filename := e.Filename
    68  	if e.Template != nil {
    69  		filename = e.Template.set.resolveFilename(e.Template, e.Filename)
    70  	}
    71  	file, err := os.Open(filename)
    72  	if err != nil {
    73  		panic(err)
    74  	}
    75  	defer file.Close()
    76  
    77  	scanner := bufio.NewScanner(file)
    78  	l := 0
    79  	for scanner.Scan() {
    80  		l++
    81  		if l == e.Line {
    82  			return scanner.Text(), true
    83  		}
    84  	}
    85  	return "", false
    86  }