Skip to content

Commit

Permalink
handle context blocks and better error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
rusq committed Mar 25, 2024
1 parent fdf58a0 commit babac09
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 33 deletions.
13 changes: 2 additions & 11 deletions internal/chunk/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"io"
"log"
"path/filepath"
"runtime"
"runtime/trace"
"sort"
"strings"
Expand Down Expand Up @@ -126,24 +125,16 @@ func indexChunks(dec decoder) (index, error) {
idx[id] = append(idx[id], offset)
}

logger.Default.Debugf("indexing chunks: %d: called from %v, took %s (%.2f/sec)", len(idx), caller(2), time.Since(start), float64(len(idx))/time.Since(start).Seconds())
logger.Default.Debugf("indexing chunks: %d: called from %v, took %s (%.2f/sec)", len(idx), osext.Caller(2), time.Since(start), float64(len(idx))/time.Since(start).Seconds())
return idx, nil
}

func caller(steps int) string {
name := "?"
if pc, _, _, ok := runtime.Caller(steps + 1); ok {
name = filepath.Base(runtime.FuncForPC(pc).Name())
}
return name
}

// ensure ensures that the file index was generated.
//
// TODO: maybe it shouldn't panic.
func (f *File) ensure() {
if f.idx == nil {
log.Panicf("internal error: %s called before File.Open", caller(1))
log.Panicf("internal error: %s called before File.Open", osext.Caller(1))
}
}

Expand Down
14 changes: 14 additions & 0 deletions internal/osext/caller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package osext

import (
"path/filepath"
"runtime"
)

func Caller(steps int) string {
name := "?"
if pc, _, _, ok := runtime.Caller(steps + 1); ok {
name = filepath.Base(runtime.FuncForPC(pc).Name())
}
return name
}
40 changes: 37 additions & 3 deletions internal/viewer/renderer/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package renderer

import (
"encoding/json"
"errors"
"fmt"
"html"
"html/template"
"log/slog"
"os"
"strings"

"github.com/rusq/slack"
"github.com/rusq/slackdump/v3/internal/osext"
)

const debug = true
Expand Down Expand Up @@ -62,5 +63,38 @@ var blockAction = map[slack.MessageBlockType]func(slack.Block) (string, error){
slack.MBTContext: mbtContext,
}

// ErrIncorrectBlockType is returned when the block type is not handled.
var ErrIncorrectBlockType = errors.New("incorrect block type")
const stackframe = 1

type ErrIncorrectBlockType struct {
Caller string
Want any
Got any
}

func (e *ErrIncorrectBlockType) Error() string {
return fmt.Sprintf("incorrect block type for block %s: want %T, got %T", e.Caller, e.Want, e.Got)
}

func NewErrIncorrectType(want, got any) error {
return &ErrIncorrectBlockType{
Caller: osext.Caller(stackframe),
Want: want,
Got: got,
}
}

type ErrMissingHandler struct {
Caller string
Type any
}

func (e *ErrMissingHandler) Error() string {
return fmt.Sprintf("missing handler for type %v called in %s", e.Type, e.Caller)
}

func NewErrMissingHandler(t any) error {
return &ErrMissingHandler{
Caller: osext.Caller(stackframe),
Type: t,
}
}
15 changes: 12 additions & 3 deletions internal/viewer/renderer/slack_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import (
func mbtContext(ib slack.Block) (string, error) {
b, ok := ib.(*slack.ContextBlock)
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrIncorrectType(&slack.ContextBlock{}, ib)
}
var buf strings.Builder
for _, el := range b.ContextElements.Elements {
fn, ok := contextElementHandlers[el.MixedElementType()]
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrMissingHandler(el.MixedElementType())
}
s, err := fn(el)
if err != nil {
Expand All @@ -30,12 +30,21 @@ func mbtContext(ib slack.Block) (string, error) {

var contextElementHandlers = map[slack.MixedElementType]func(slack.MixedElement) (string, error){
slack.MixedElementImage: metImage,
slack.MixedElementText: metText,
}

func metImage(ie slack.MixedElement) (string, error) {
e, ok := ie.(*slack.ImageBlockElement)
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrIncorrectType(&slack.ImageBlockElement{}, ie)
}
return fmt.Sprintf(`<img src="%s" alt="%s">`, e.ImageURL, e.AltText), nil
}

func metText(ie slack.MixedElement) (string, error) {
e, ok := ie.(*slack.TextBlockObject)
if !ok {
return "", NewErrIncorrectType(&slack.TextBlockObject{}, ie)
}
return e.Text, nil
}
2 changes: 1 addition & 1 deletion internal/viewer/renderer/slack_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func mbtImage(ib slack.Block) (string, error) {
b, ok := ib.(*slack.ImageBlock)
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrIncorrectType(&slack.ImageBlock{}, ib)
}
return fmt.Sprintf(`<img src="%s" alt="%s">`, b.ImageURL, b.AltText), nil
}
30 changes: 15 additions & 15 deletions internal/viewer/renderer/slack_rich_text.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ func init() {
func mbtRichText(ib slack.Block) (string, error) {
b, ok := ib.(*slack.RichTextBlock)
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrIncorrectType(&slack.RichTextBlock{}, ib)
}
var buf strings.Builder
for _, el := range b.Elements {
fn, ok := rteTypeHandlers[el.RichTextElementType()]
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrMissingHandler(el.RichTextElementType())
}
s, err := fn(el)
if err != nil {
Expand All @@ -40,13 +40,13 @@ func mbtRichText(ib slack.Block) (string, error) {
func rteSection(ie slack.RichTextElement) (string, error) {
e, ok := ie.(*slack.RichTextSection)
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrIncorrectType(&slack.RichTextSection{}, ie)
}
var buf strings.Builder
for _, el := range e.Elements {
fn, ok := rtseHandlers[el.RichTextSectionElementType()]
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrMissingHandler(el.RichTextSectionElementType())
}
s, err := fn(el)
if err != nil {
Expand All @@ -69,7 +69,7 @@ var rtseHandlers = map[slack.RichTextSectionElementType]func(slack.RichTextSecti
func rtseText(ie slack.RichTextSectionElement) (string, error) {
e, ok := ie.(*slack.RichTextSectionTextElement)
if !ok {
return "", fmt.Errorf("%T: %w", ie, ErrIncorrectBlockType)
return "", NewErrIncorrectType(&slack.RichTextSectionTextElement{}, ie)
}
var t = strings.Replace(e.Text, "\n", "<br>", -1)

Expand Down Expand Up @@ -98,7 +98,7 @@ func applyStyle(s string, style *slack.RichTextSectionTextStyle) string {
func rtseLink(ie slack.RichTextSectionElement) (string, error) {
e, ok := ie.(*slack.RichTextSectionLinkElement)
if !ok {
return "", fmt.Errorf("%T: %w", ie, ErrIncorrectBlockType)
return "", NewErrIncorrectType(&slack.RichTextSectionLinkElement{}, ie)
}
if e.Text == "" {
e.Text = e.URL
Expand All @@ -109,7 +109,7 @@ func rtseLink(ie slack.RichTextSectionElement) (string, error) {
func rteList(ie slack.RichTextElement) (string, error) {
e, ok := ie.(*slack.RichTextList)
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrIncorrectType(&slack.RichTextList{}, ie)
}
// const orderedTypes = "1aAiI"
var tgOpen, tgClose string
Expand All @@ -126,7 +126,7 @@ func rteList(ie slack.RichTextElement) (string, error) {
for _, el := range e.Elements {
fn, ok := rteTypeHandlers[el.RichTextElementType()]
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrMissingHandler(el.RichTextElementType())
}
s, err := fn(el)
if err != nil {
Expand All @@ -141,14 +141,14 @@ func rteList(ie slack.RichTextElement) (string, error) {
func rteQuote(ie slack.RichTextElement) (string, error) {
e, ok := ie.(*slack.RichTextQuote)
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrIncorrectType(&slack.RichTextQuote{}, ie)
}
var buf strings.Builder
buf.WriteString("<blockquote>")
for _, el := range e.Elements {
fn, ok := rtseHandlers[el.RichTextSectionElementType()]
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrMissingHandler(el.RichTextSectionElementType())
}
s, err := fn(el)
if err != nil {
Expand All @@ -163,14 +163,14 @@ func rteQuote(ie slack.RichTextElement) (string, error) {
func rtePreformatted(ie slack.RichTextElement) (string, error) {
e, ok := ie.(*slack.RichTextPreformatted)
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrIncorrectType(&slack.RichTextPreformatted{}, ie)
}
var buf strings.Builder
buf.WriteString("<pre>")
for _, el := range e.Elements {
fn, ok := rtseHandlers[el.RichTextSectionElementType()]
if !ok {
return "", ErrIncorrectBlockType
return "", NewErrMissingHandler(el.RichTextSectionElementType())
}
s, err := fn(el)
if err != nil {
Expand All @@ -185,7 +185,7 @@ func rtePreformatted(ie slack.RichTextElement) (string, error) {
func rtseUser(ie slack.RichTextSectionElement) (string, error) {
e, ok := ie.(*slack.RichTextSectionUserElement)
if !ok {
return "", fmt.Errorf("%T: %w", ie, ErrIncorrectBlockType)
return "", NewErrIncorrectType(&slack.RichTextSectionUserElement{}, ie)
}
// TODO: link user.
return applyStyle(fmt.Sprintf("<@%s>", e.UserID), e.Style), nil
Expand All @@ -194,7 +194,7 @@ func rtseUser(ie slack.RichTextSectionElement) (string, error) {
func rtseEmoji(ie slack.RichTextSectionElement) (string, error) {
e, ok := ie.(*slack.RichTextSectionEmojiElement)
if !ok {
return "", fmt.Errorf("%T: %w", ie, ErrIncorrectBlockType)
return "", NewErrIncorrectType(&slack.RichTextSectionEmojiElement{}, ie)
}
// TODO: resolve and render emoji.
return applyStyle(fmt.Sprintf(":%s:", e.Name), e.Style), nil
Expand All @@ -203,7 +203,7 @@ func rtseEmoji(ie slack.RichTextSectionElement) (string, error) {
func rtseChannel(ie slack.RichTextSectionElement) (string, error) {
e, ok := ie.(*slack.RichTextSectionChannelElement)
if !ok {
return "", fmt.Errorf("%T: %w", ie, ErrIncorrectBlockType)
return "", NewErrIncorrectType(&slack.RichTextSectionChannelElement{}, ie)
}
return applyStyle(fmt.Sprintf("<#%s>", e.ChannelID), e.Style), nil
}

0 comments on commit babac09

Please sign in to comment.