func (c *Client) Wrap(f interface{}, args ...interface{}) (err interface{}) {
	return c.WrapWithArgs(f, false, args...)
}
Wrap calls f and then recovers and reports a panic to Rollbar if it occurs.
If an error is captured it is subsequently returned.
package rollbar
import (
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"os"
	"reflect"
	"regexp"
	"runtime"
	"time"
)
type Client struct {
	io.Closer
	Transport     Transport
	Telemetry     *Telemetry
	configuration configuration
	diagnostic    diagnostic
}
func New(token, environment, codeVersion, serverHost, serverRoot string) *Client {
	return NewAsync(token, environment, codeVersion, serverHost, serverRoot)
}
func NewAsync(token, environment, codeVersion, serverHost, serverRoot string) *Client {
	configuration := createConfiguration(token, environment, codeVersion, serverHost, serverRoot)
	transport := NewTransport(token, configuration.endpoint)
	diagnostic := createDiagnostic()
	return &Client{
		Transport:     transport,
		Telemetry:     NewTelemetry(nil),
		configuration: configuration,
		diagnostic:    diagnostic,
	}
}
func NewSync(token, environment, codeVersion, serverHost, serverRoot string) *Client {
	configuration := createConfiguration(token, environment, codeVersion, serverHost, serverRoot)
	transport := NewSyncTransport(token, configuration.endpoint)
	diagnostic := createDiagnostic()
	return &Client{
		Transport:     transport,
		Telemetry:     NewTelemetry(nil),
		configuration: configuration,
		diagnostic:    diagnostic,
	}
}
func (c *Client) CaptureTelemetryEvent(eventType, eventlevel string, eventData map[string]interface{}) {
	data := map[string]interface{}{}
	data["body"] = eventData
	data["type"] = eventType
	data["level"] = eventlevel
	data["source"] = "client"
	data["timestamp_ms"] = time.Now().UnixNano() / int64(time.Millisecond)
	c.Telemetry.Queue.Push(data)
}
func (c *Client) SetTelemetry(options ...OptionFunc) {
	c.Telemetry = NewTelemetry(c.configuration.scrubHeaders, options...)
}
func (c *Client) SetEnabled(enabled bool) {
	c.configuration.enabled = enabled
}
func (c *Client) SetToken(token string) {
	c.configuration.token = token
	c.Transport.SetToken(token)
}
func (c *Client) SetEnvironment(environment string) {
	c.configuration.environment = environment
}
func (c *Client) SetEndpoint(endpoint string) {
	c.configuration.endpoint = endpoint
	c.Transport.SetEndpoint(endpoint)
}
func (c *Client) SetPlatform(platform string) {
	c.configuration.platform = platform
}
func (c *Client) SetCodeVersion(codeVersion string) {
	c.configuration.codeVersion = codeVersion
}
func (c *Client) SetServerHost(serverHost string) {
	c.configuration.serverHost = serverHost
}
func (c *Client) SetServerRoot(serverRoot string) {
	c.configuration.serverRoot = serverRoot
}
func (c *Client) SetCustom(custom map[string]interface{}) {
	c.configuration.custom = custom
}
func (c *Client) SetPerson(id, username, email string) {
	person := Person{
		Id:       id,
		Username: username,
		Email:    email,
	}
	c.configuration.person = person
}
func (c *Client) ClearPerson() {
	person := Person{}
	c.configuration.person = person
}
func (c *Client) SetFingerprint(fingerprint bool) {
	c.configuration.fingerprint = fingerprint
}
func (c *Client) SetLogger(logger ClientLogger) {
	c.Transport.SetLogger(logger)
}
func (c *Client) SetScrubHeaders(headers *regexp.Regexp) {
	c.configuration.scrubHeaders = headers
	c.Telemetry.Network.ScrubHeaders = headers
}
func (c *Client) SetScrubFields(fields *regexp.Regexp) {
	c.configuration.scrubFields = fields
}
func (c *Client) SetTransform(transform func(map[string]interface{})) {
	c.configuration.transform = transform
}
func (c *Client) SetUnwrapper(unwrapper UnwrapperFunc) {
	c.configuration.unwrapper = unwrapper
}
func (c *Client) SetStackTracer(stackTracer StackTracerFunc) {
	c.configuration.stackTracer = stackTracer
}
func (c *Client) SetCheckIgnore(checkIgnore func(string) bool) {
	c.configuration.checkIgnore = checkIgnore
}
func (c *Client) SetCaptureIp(captureIp captureIp) {
	c.configuration.captureIp = captureIp
}
func (c *Client) SetRetryAttempts(retryAttempts int) {
	c.Transport.SetRetryAttempts(retryAttempts)
}
func (c *Client) SetItemsPerMinute(itemsPerMinute int) {
	c.configuration.itemsPerMinute = itemsPerMinute
	c.Transport.SetItemsPerMinute(itemsPerMinute)
}
func (c *Client) SetPrintPayloadOnError(printPayloadOnError bool) {
	c.Transport.SetPrintPayloadOnError(printPayloadOnError)
}
func (c *Client) SetHTTPClient(httpClient *http.Client) {
	c.Transport.SetHTTPClient(httpClient)
}
func (c *Client) Token() string {
	return c.configuration.token
}
func (c *Client) ItemsPerMinute() int {
	return c.configuration.itemsPerMinute
}
func (c *Client) Environment() string {
	return c.configuration.environment
}
func (c *Client) Endpoint() string {
	return c.configuration.endpoint
}
func (c *Client) Platform() string {
	return c.configuration.platform
}
func (c *Client) CodeVersion() string {
	return c.configuration.codeVersion
}
func (c *Client) ServerHost() string {
	return c.configuration.serverHost
}
func (c *Client) ServerRoot() string {
	return c.configuration.serverRoot
}
func (c *Client) Custom() map[string]interface{} {
	return c.configuration.custom
}
func (c *Client) Fingerprint() bool {
	return c.configuration.fingerprint
}
func (c *Client) ScrubHeaders() *regexp.Regexp {
	return c.configuration.scrubHeaders
}
func (c *Client) ScrubFields() *regexp.Regexp {
	return c.configuration.scrubFields
}
func (c *Client) CaptureIp() captureIp {
	return c.configuration.captureIp
}
var noExtras map[string]interface{}
func (c *Client) ErrorWithLevel(level string, err error) {
	c.ErrorWithExtras(level, err, noExtras)
}
func (c *Client) Errorf(level string, format string, args ...interface{}) {
	c.ErrorWithStackSkipWithExtras(level, fmt.Errorf(format, args...), 1, noExtras)
}
func (c *Client) ErrorWithExtras(level string, err error, extras map[string]interface{}) {
	c.ErrorWithStackSkipWithExtras(level, err, 1, extras)
}
func (c *Client) ErrorWithExtrasAndContext(ctx context.Context, level string, err error, extras map[string]interface{}) {
	c.ErrorWithStackSkipWithExtrasAndContext(ctx, level, err, 1, extras)
}
func (c *Client) RequestError(level string, r *http.Request, err error) {
	c.RequestErrorWithExtras(level, r, err, noExtras)
}
func (c *Client) RequestErrorWithExtras(level string, r *http.Request, err error, extras map[string]interface{}) {
	c.RequestErrorWithStackSkipWithExtras(level, r, err, 1, extras)
}
func (c *Client) RequestErrorWithExtrasAndContext(ctx context.Context, level string, r *http.Request, err error, extras map[string]interface{}) {
	c.RequestErrorWithStackSkipWithExtrasAndContext(ctx, level, r, err, 1, extras)
}
func (c *Client) ErrorWithStackSkip(level string, err error, skip int) {
	c.ErrorWithStackSkipWithExtras(level, err, skip, noExtras)
}
func (c *Client) ErrorWithStackSkipWithExtras(level string, err error, skip int, extras map[string]interface{}) {
	c.ErrorWithStackSkipWithExtrasAndContext(context.TODO(), level, err, skip, extras)
}
func (c *Client) ErrorWithStackSkipWithExtrasAndContext(ctx context.Context, level string, err error, skip int, extras map[string]interface{}) {
	if !c.configuration.enabled {
		return
	}
	body := c.buildBody(ctx, level, err.Error(), extras)
	telemetry := c.Telemetry.GetQueueItems()
	addErrorToBody(c.configuration, body, err, skip, telemetry)
	c.push(body)
}
func (c *Client) RequestErrorWithStackSkip(level string, r *http.Request, err error, skip int) {
	c.RequestErrorWithStackSkipWithExtras(level, r, err, skip, noExtras)
}
func (c *Client) RequestErrorWithStackSkipWithExtras(level string, r *http.Request, err error, skip int, extras map[string]interface{}) {
	c.RequestErrorWithStackSkipWithExtrasAndContext(context.TODO(), level, r, err, skip, extras)
}
func (c *Client) RequestErrorWithStackSkipWithExtrasAndContext(ctx context.Context, level string, r *http.Request, err error, skip int, extras map[string]interface{}) {
	if !c.configuration.enabled {
		return
	}
	body := c.buildBody(ctx, level, err.Error(), extras)
	telemetry := c.Telemetry.GetQueueItems()
	data := addErrorToBody(c.configuration, body, err, skip, telemetry)
	data["request"] = c.requestDetails(r)
	c.push(body)
}
func (c *Client) Message(level string, msg string) {
	c.MessageWithExtras(level, msg, noExtras)
}
func (c *Client) MessageWithExtras(level string, msg string, extras map[string]interface{}) {
	c.MessageWithExtrasAndContext(context.TODO(), level, msg, extras)
}
func (c *Client) MessageWithExtrasAndContext(ctx context.Context, level string, msg string, extras map[string]interface{}) {
	if !c.configuration.enabled {
		return
	}
	body := c.buildBody(ctx, level, msg, extras)
	data := body["data"].(map[string]interface{})
	dataBody := messageBody(msg)
	telemetry := c.Telemetry.GetQueueItems()
	dataBody["telemetry"] = telemetry
	data["body"] = dataBody
	c.push(body)
}
func (c *Client) RequestMessage(level string, r *http.Request, msg string) {
	c.RequestMessageWithExtras(level, r, msg, noExtras)
}
func (c *Client) RequestMessageWithExtras(level string, r *http.Request, msg string, extras map[string]interface{}) {
	c.RequestMessageWithExtrasAndContext(context.TODO(), level, r, msg, extras)
}
func (c *Client) RequestMessageWithExtrasAndContext(ctx context.Context, level string, r *http.Request, msg string, extras map[string]interface{}) {
	if !c.configuration.enabled {
		return
	}
	body := c.buildBody(ctx, level, msg, extras)
	data := body["data"].(map[string]interface{})
	dataBody := messageBody(msg)
	telemetry := c.Telemetry.GetQueueItems()
	dataBody["telemetry"] = telemetry
	data["body"] = dataBody
	data["request"] = c.requestDetails(r)
	c.push(body)
}
func (c *Client) LogPanic(err interface{}, wait bool) {
	switch val := err.(type) {
	case nil:
		return
	case error:
		if c.configuration.checkIgnore(val.Error()) {
			return
		}
		c.ErrorWithStackSkip(CRIT, val, 2)
	default:
		str := fmt.Sprint(val)
		if c.configuration.checkIgnore(str) {
			return
		}
		errValue := errors.New(str)
		c.ErrorWithStackSkip(CRIT, errValue, 2)
	}
	if wait {
		c.Wait()
	}
}
func (c *Client) WrapWithArgs(f interface{}, wait bool, inArgs ...interface{}) (err interface{}) {
	if f == nil {
		err = fmt.Errorf("function is nil")
		return
	}
	funcType := reflect.TypeOf(f)
	funcValue := reflect.ValueOf(f)
	if funcType.Kind() != reflect.Func {
		err = fmt.Errorf("function kind %s is not %s", funcType.Kind(), reflect.Func)
		return
	}
	argValues := make([]reflect.Value, len(inArgs))
	for i, v := range inArgs {
		argValues[i] = reflect.ValueOf(v)
	}
	handler := func(args []reflect.Value) []reflect.Value {
		defer func() {
			err = recover()
			c.LogPanic(err, wait)
		}()
		return funcValue.Call(args)
	}
	handler(argValues)
	return
}