github.com/blend/go-sdk@v1.20240719.1/logger/error_event.go (about)

     1  /*
     2  
     3  Copyright (c) 2024 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package logger
     9  
    10  import (
    11  	"context"
    12  	"encoding/json"
    13  	"fmt"
    14  	"io"
    15  )
    16  
    17  // these are compile time assertions
    18  var (
    19  	_ Event        = (*ErrorEvent)(nil)
    20  	_ TextWritable = (*ErrorEvent)(nil)
    21  	_ JSONWritable = (*ErrorEvent)(nil)
    22  )
    23  
    24  // NewErrorEvent returns a new error event.
    25  func NewErrorEvent(flag string, err error, options ...ErrorEventOption) ErrorEvent {
    26  	ee := ErrorEvent{
    27  		Flag: flag,
    28  		Err:  err,
    29  	}
    30  	for _, opt := range options {
    31  		opt(&ee)
    32  	}
    33  	return ee
    34  }
    35  
    36  // NewErrorEventListener returns a new error event listener.
    37  func NewErrorEventListener(listener func(context.Context, ErrorEvent)) Listener {
    38  	return func(ctx context.Context, e Event) {
    39  		if typed, isTyped := e.(ErrorEvent); isTyped {
    40  			listener(ctx, typed)
    41  		}
    42  	}
    43  }
    44  
    45  // NewScopedErrorEventListener returns a new error event listener that listens
    46  // to specified scopes
    47  func NewScopedErrorEventListener(listener func(context.Context, ErrorEvent), scopes *Scopes) Listener {
    48  	return func(ctx context.Context, e Event) {
    49  		if typed, isTyped := e.(ErrorEvent); isTyped {
    50  			if scopes.IsEnabled(GetPath(ctx)...) {
    51  				listener(ctx, typed)
    52  			}
    53  		}
    54  	}
    55  }
    56  
    57  // NewErrorEventFilter returns a new error event filter.
    58  func NewErrorEventFilter(filter func(context.Context, ErrorEvent) (ErrorEvent, bool)) Filter {
    59  	return func(ctx context.Context, e Event) (Event, bool) {
    60  		if typed, isTyped := e.(ErrorEvent); isTyped {
    61  			return filter(ctx, typed)
    62  		}
    63  		return e, false
    64  	}
    65  }
    66  
    67  // ErrorEventOption is an option for error events.
    68  type ErrorEventOption = func(*ErrorEvent)
    69  
    70  // OptErrorEventState sets the state on an error event.
    71  func OptErrorEventState(state interface{}) ErrorEventOption {
    72  	return func(ee *ErrorEvent) {
    73  		ee.State = state
    74  	}
    75  }
    76  
    77  // OptErrorEventRestricted sets the restricted field on an error event.
    78  func OptErrorEventRestricted(restricted bool) ErrorEventOption {
    79  	return func(ee *ErrorEvent) {
    80  		ee.Restricted = restricted
    81  	}
    82  }
    83  
    84  // ErrorEvent is an event that wraps an error.
    85  type ErrorEvent struct {
    86  	Flag       string
    87  	Err        error
    88  	State      interface{}
    89  	Restricted bool
    90  }
    91  
    92  // GetFlag implements Event.
    93  func (ee ErrorEvent) GetFlag() string { return ee.Flag }
    94  
    95  // WriteText writes the text version of an error.
    96  func (ee ErrorEvent) WriteText(formatter TextFormatter, output io.Writer) {
    97  	if ee.Err != nil {
    98  		fmt.Fprintf(output, "%+v", ee.Err)
    99  	}
   100  }
   101  
   102  // Decompose implements JSONWritable.
   103  func (ee ErrorEvent) Decompose() map[string]interface{} {
   104  	if ee.Err == nil {
   105  		return nil
   106  	}
   107  
   108  	if _, ok := ee.Err.(json.Marshaler); ok {
   109  		return map[string]interface{}{
   110  			"err":           ee.Err,
   111  			FieldRestricted: ee.Restricted,
   112  		}
   113  	}
   114  	return map[string]interface{}{
   115  		"err":           ee.Err.Error(),
   116  		FieldRestricted: ee.Restricted,
   117  	}
   118  }