Convert panics to errors for public interface

This commit is contained in:
Niklas Fasching 2018-12-14 16:24:53 +01:00
parent f28f400d7e
commit 04df30a7b5
5 changed files with 52 additions and 15 deletions

View file

@ -9,6 +9,7 @@ import (
)
type Document struct {
Path string
tokens []token
Nodes []Node
Footnotes *Footnotes
@ -17,6 +18,7 @@ type Document struct {
AutoLink bool
BufferSettings map[string]string
DefaultSettings map[string]string
Error error
}
type Writer interface {
@ -77,24 +79,45 @@ func NewDocument() *Document {
}
}
func (d *Document) Write(w Writer) Writer {
if d.Nodes == nil {
panic("cannot Write() empty document: you must call Parse() first")
func (d *Document) Write(w Writer) (out string, err error) {
defer func() {
if recovered := recover(); recovered != nil {
err = fmt.Errorf("could not write output: %s", recovered)
}
}()
if d.Error != nil {
return "", d.Error
} else if d.Nodes == nil {
return "", fmt.Errorf("could not write output: parse was not called")
}
w.before(d)
w.writeNodes(d.Nodes...)
w.after(d)
return w
return w.String(), err
}
func (d *Document) Parse(input io.Reader) *Document {
defer func() {
if err := recover(); err != nil {
d.Error = fmt.Errorf("could not parse input: %s", err)
}
}()
if d.tokens != nil {
d.Error = fmt.Errorf("parse was called multiple times")
}
d.tokenize(input)
_, nodes := d.parseMany(0, func(d *Document, i int) bool { return !(i < len(d.tokens)) })
d.Nodes = nodes
return d
}
func (d *Document) FrontMatter(input io.Reader, f func(string, string) interface{}) map[string]interface{} {
func (d *Document) FrontMatter(input io.Reader, f func(string, string) interface{}) (_ map[string]interface{}, err error) {
defer func() {
d.tokens = nil
if recovered := recover(); recovered != nil {
err = fmt.Errorf("could not parse input: %s", recovered)
}
}()
d.tokenize(input)
d.parseMany(0, func(d *Document, i int) bool {
if !(i < len(d.tokens)) {
@ -107,7 +130,7 @@ func (d *Document) FrontMatter(input io.Reader, f func(string, string) interface
for k, v := range d.BufferSettings {
frontMatter[k] = f(k, v)
}
return frontMatter
return frontMatter, err
}
func (d *Document) tokenize(input io.Reader) {
@ -117,7 +140,7 @@ func (d *Document) tokenize(input io.Reader) {
d.tokens = append(d.tokens, tokenize(scanner.Text()))
}
if err := scanner.Err(); err != nil {
panic(err)
d.Error = fmt.Errorf("could not tokenize input: %s", err)
}
}