@ -254,8 +254,12 @@ func (p *PromParser) nextToken() token {
}
}
}
}
func parseError ( exp string , got token ) error {
func ( p * PromParser ) parseError ( exp string , got token ) error {
return fmt . Errorf ( "%s, got %q" , exp , got )
e := p . l . i + 1
if len ( p . l . b ) <= e {
e = len ( p . l . b )
}
return fmt . Errorf ( "%s, got %q (%q) while parsing: %q" , exp , p . l . b [ p . l . start : e ] , got , p . l . b [ p . start : e ] )
}
}
// Next advances the parser to the next sample. It returns false if no
// Next advances the parser to the next sample. It returns false if no
@ -278,7 +282,7 @@ func (p *PromParser) Next() (Entry, error) {
case tMName :
case tMName :
p . offsets = append ( p . offsets , p . l . start , p . l . i )
p . offsets = append ( p . offsets , p . l . start , p . l . i )
default :
default :
return EntryInvalid , parseError ( "expected metric name after " + t . String ( ) , t2 )
return EntryInvalid , p . parseError ( "expected metric name after " + t . String ( ) , t2 )
}
}
switch t2 := p . nextToken ( ) ; t2 {
switch t2 := p . nextToken ( ) ; t2 {
case tText :
case tText :
@ -308,11 +312,11 @@ func (p *PromParser) Next() (Entry, error) {
}
}
case tHelp :
case tHelp :
if ! utf8 . Valid ( p . text ) {
if ! utf8 . Valid ( p . text ) {
return EntryInvalid , fmt . Errorf ( "help text is not a valid utf8 string" )
return EntryInvalid , fmt . Errorf ( "help text %q is not a valid utf8 string" , p . text )
}
}
}
}
if t := p . nextToken ( ) ; t != tLinebreak {
if t := p . nextToken ( ) ; t != tLinebreak {
return EntryInvalid , parseError ( "linebreak expected after metadata" , t )
return EntryInvalid , p . parseError ( "linebreak expected after metadata" , t )
}
}
switch t {
switch t {
case tHelp :
case tHelp :
@ -323,7 +327,7 @@ func (p *PromParser) Next() (Entry, error) {
case tComment :
case tComment :
p . text = p . l . buf ( )
p . text = p . l . buf ( )
if t := p . nextToken ( ) ; t != tLinebreak {
if t := p . nextToken ( ) ; t != tLinebreak {
return EntryInvalid , parseError ( "linebreak expected after comment" , t )
return EntryInvalid , p . parseError ( "linebreak expected after comment" , t )
}
}
return EntryComment , nil
return EntryComment , nil
@ -340,10 +344,10 @@ func (p *PromParser) Next() (Entry, error) {
t2 = p . nextToken ( )
t2 = p . nextToken ( )
}
}
if t2 != tValue {
if t2 != tValue {
return EntryInvalid , parseError ( "expected value after metric" , t2 )
return EntryInvalid , p . parseError ( "expected value after metric" , t2 )
}
}
if p . val , err = parseFloat ( yoloString ( p . l . buf ( ) ) ) ; err != nil {
if p . val , err = parseFloat ( yoloString ( p . l . buf ( ) ) ) ; err != nil {
return EntryInvalid , err
return EntryInvalid , fmt . Errorf ( "%v while parsing: %q" , err , p . l . b [ p . start : p . l . i ] )
}
}
// Ensure canonical NaN value.
// Ensure canonical NaN value.
if math . IsNaN ( p . val ) {
if math . IsNaN ( p . val ) {
@ -356,18 +360,18 @@ func (p *PromParser) Next() (Entry, error) {
case tTimestamp :
case tTimestamp :
p . hasTS = true
p . hasTS = true
if p . ts , err = strconv . ParseInt ( yoloString ( p . l . buf ( ) ) , 10 , 64 ) ; err != nil {
if p . ts , err = strconv . ParseInt ( yoloString ( p . l . buf ( ) ) , 10 , 64 ) ; err != nil {
return EntryInvalid , err
return EntryInvalid , fmt . Errorf ( "%v while parsing: %q" , err , p . l . b [ p . start : p . l . i ] )
}
}
if t2 := p . nextToken ( ) ; t2 != tLinebreak {
if t2 := p . nextToken ( ) ; t2 != tLinebreak {
return EntryInvalid , parseError ( "expected next entry after timestamp" , t2 )
return EntryInvalid , p . parseError ( "expected next entry after timestamp" , t2 )
}
}
default :
default :
return EntryInvalid , parseError ( "expected timestamp or new record" , t )
return EntryInvalid , p . parseError ( "expected timestamp or new record" , t )
}
}
return EntrySeries , nil
return EntrySeries , nil
default :
default :
err = fmt . Errorf ( "%q is not a valid start token", t )
err = p . parseError ( "expected a valid start token", t )
}
}
return EntryInvalid , err
return EntryInvalid , err
}
}
@ -380,18 +384,18 @@ func (p *PromParser) parseLVals() error {
return nil
return nil
case tLName :
case tLName :
default :
default :
return parseError ( "expected label name" , t )
return p . parseError ( "expected label name" , t )
}
}
p . offsets = append ( p . offsets , p . l . start , p . l . i )
p . offsets = append ( p . offsets , p . l . start , p . l . i )
if t := p . nextToken ( ) ; t != tEqual {
if t := p . nextToken ( ) ; t != tEqual {
return parseError ( "expected equal" , t )
return p . parseError ( "expected equal" , t )
}
}
if t := p . nextToken ( ) ; t != tLValue {
if t := p . nextToken ( ) ; t != tLValue {
return parseError ( "expected label value" , t )
return p . parseError ( "expected label value" , t )
}
}
if ! utf8 . Valid ( p . l . buf ( ) ) {
if ! utf8 . Valid ( p . l . buf ( ) ) {
return fmt . Errorf ( "invalid UTF-8 label value" )
return fmt . Errorf ( "invalid UTF-8 label value: %q " , p . l . buf ( ) )
}
}
// The promlexer ensures the value string is quoted. Strip first
// The promlexer ensures the value string is quoted. Strip first