Skip to content

Commit

Permalink
Better error handling. Funnels calls to panic to a single function th…
Browse files Browse the repository at this point in the history
…at outputs the state of the file processing at the time of the panic()
  • Loading branch information
hectorcorrea committed Jun 3, 2019
1 parent 38e240f commit 1ddc7b8
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 24 deletions.
19 changes: 14 additions & 5 deletions dirEntry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,32 @@ type DirEntry struct {
Tag string
Length int
StartsAt int
raw string
}

func NewDirEntry(entry string) (DirEntry, error) {
if len(entry) != 12 {
return DirEntry{}, errors.New("Incomplete field definition")
return DirEntry{raw: entry}, errors.New("Incomplete field definition")
}

l, _ := strconv.Atoi(entry[3:7])
s, _ := strconv.Atoi(entry[7:])
length, _ := strconv.Atoi(entry[3:7])
if length == 0 {
return DirEntry{raw: entry}, errors.New("Empty directory entry detected")
}

startsAt, _ := strconv.Atoi(entry[7:])
dir := DirEntry{
Tag: entry[0:3],
Length: l,
StartsAt: s,
Length: length,
StartsAt: startsAt,
raw: entry,
}
return dir, nil
}

func (d DirEntry) String() string {
if d.Tag == "" {
return fmt.Sprintf("raw: %s", d.raw)
}
return fmt.Sprintf("tag: %s len: %d starts at: %d", d.Tag, d.Length, d.StartsAt)
}
52 changes: 33 additions & 19 deletions marcfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package main

import (
"bufio"
"errors"
"fmt"
"io"
"os"
)
Expand All @@ -14,10 +16,11 @@ type Processor interface {
}

type MarcFile struct {
Name string
f *os.File
records int
outputCount int
Name string
f *os.File
records int
outputCount int
lastGoodRecord Record
}

func NewMarcFile(filename string) (MarcFile, error) {
Expand All @@ -28,6 +31,10 @@ func NewMarcFile(filename string) (MarcFile, error) {
return MarcFile{Name: filename, f: f, records: 0}, nil
}

func (file *MarcFile) Close() {
file.f.Close()
}

func (file *MarcFile) ReadAll(processor Processor, searchValue string) error {
processor.Header()
for {
Expand All @@ -39,19 +46,15 @@ func (file *MarcFile) ReadAll(processor Processor, searchValue string) error {
return err
}

file.records += 1
file.records++

if record.IsMatch(searchValue) {
if file.outputCount > 0 {
processor.Separator()
}
processor.ProcessRecord(file, record)
file.outputCount += 1
file.outputCount++
}

// if file.outputCount == 10000 {
// break
// }
}
file.f.Close()
processor.Footer()
Expand All @@ -66,22 +69,20 @@ func (file *MarcFile) readRecord(processor Processor) (Record, error) {

directory, err := file.readDirectory()
if err != nil {
panic(err)
file.stopProcessing(err)
}

fields := file.readValues(directory)
record := Record{
Leader: leader,
Directory: directory,
Fields: fields,
Pos: file.records,
}
file.lastGoodRecord = record
return record, nil
}

func (file *MarcFile) Close() {
file.f.Close()
}

func (file *MarcFile) readLeader() (Leader, error) {
bytes := make([]byte, 24)
_, err := file.f.Read(bytes)
Expand All @@ -108,7 +109,8 @@ func (file *MarcFile) readDirectory() ([]DirEntry, error) {
entry := ss[start : start+12]
field, err := NewDirEntry(entry)
if err != nil {
return nil, err
errMsg := fmt.Sprintf("%s (raw directory: %s)", err, ss)
return nil, errors.New(errMsg)
}
directory[i] = field
}
Expand All @@ -129,7 +131,10 @@ func (file *MarcFile) readValues(directory []DirEntry) Fields {
buffer := make([]byte, entry.Length)
n, err := file.f.Read(buffer)
if err != nil && err != io.EOF {
panic(err)
file.stopProcessing(err)
}
if n <= 0 {
file.stopProcessing(errors.New("Value of length zero detected"))
}
value := string(buffer[:n-1]) // -1 to exclude the record separator character (0x1e)
field := NewField(entry.Tag, value)
Expand All @@ -139,11 +144,20 @@ func (file *MarcFile) readValues(directory []DirEntry) Fields {
eor := make([]byte, 1)
n, err := file.f.Read(eor)
if n != 1 {
panic("End of record byte not found")
file.stopProcessing(errors.New("End of record byte not found"))
}

if err != nil {
panic(err)
file.stopProcessing(err)
}
return fields
}

func (file *MarcFile) stopProcessing(err error) {
msg := fmt.Sprintf("Records processed: %d\r\n", file.records)
if file.records > 0 {
msg += fmt.Sprintf("Last record processed: %s\r\n", file.lastGoodRecord)
}
msg += fmt.Sprintf("Error: %s", err)
panic(msg)
}
5 changes: 5 additions & 0 deletions record.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"fmt"
"strings"
)

Expand All @@ -22,3 +23,7 @@ func (r Record) IsMatch(searchValue string) bool {
}
return false
}

func (r Record) String() string {
return fmt.Sprintf("Leader: %s", r.Leader)
}

0 comments on commit 1ddc7b8

Please sign in to comment.