diff options
| author | s <[email protected]> | 2025-11-26 09:06:15 -0500 |
|---|---|---|
| committer | s <[email protected]> | 2025-11-26 09:06:15 -0500 |
| commit | 7d6eb2f1a38e2265751cd61a43769959405866b4 (patch) | |
| tree | 99eba2542cd2ba6f30d6e2ad1c3fc53bcb5b5901 | |
| parent | cbc521467a3cca7a17e6f691a9c7fa34f4da3e24 (diff) | |
| download | dborg-7d6eb2f1a38e2265751cd61a43769959405866b4.tar.gz dborg-7d6eb2f1a38e2265751cd61a43769959405866b4.zip | |
feat: add debug flag to enable raw api response output
| -rw-r--r-- | cmd/helpers.go | 4 | ||||
| -rw-r--r-- | cmd/root.go | 8 | ||||
| -rw-r--r-- | cmd/sl.go | 2 | ||||
| -rw-r--r-- | internal/client/skiptrace.go | 48 | ||||
| -rw-r--r-- | internal/config/config.go | 6 |
5 files changed, 59 insertions, 9 deletions
diff --git a/cmd/helpers.go b/cmd/helpers.go index f53f235..133fb0a 100644 --- a/cmd/helpers.go +++ b/cmd/helpers.go @@ -8,11 +8,11 @@ import ( ) func newClient() (*client.Client, error) { - return client.New(config.New()) + return client.New(config.New().WithDebug(debugOutput)) } func newUnauthenticatedClient() (*client.Client, error) { - return client.NewUnauthenticated(config.New()) + return client.NewUnauthenticated(config.New().WithDebug(debugOutput)) } func checkError(errorMsg string) error { diff --git a/cmd/root.go b/cmd/root.go index c4239ba..292e96d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -9,7 +9,8 @@ import ( ) var ( - jsonOutput bool + jsonOutput bool + debugOutput bool ) var rootCmd = &cobra.Command{ @@ -33,8 +34,13 @@ func Execute() { func init() { rootCmd.PersistentFlags().BoolVarP(&jsonOutput, "json", "j", false, "Output raw JSON instead of formatted text") + rootCmd.PersistentFlags().BoolVarP(&debugOutput, "debug", "d", false, "Enable debug output (shows raw API responses)") } func IsJSONOutput() bool { return jsonOutput } + +func IsDebugOutput() bool { + return debugOutput +} @@ -23,7 +23,7 @@ func init() { slCmd.Flags().StringP("ingest_start_date", "i", "", "Ingest timestamp start date") slCmd.Flags().StringP("ingest_end_date", "e", "", "Ingest timestamp end date") slCmd.Flags().StringP("posted_start_date", "p", "", "Date posted start date") - slCmd.Flags().StringP("posted_end_date", "d", "", "Date posted end date") + slCmd.Flags().StringP("posted_end_date", "D", "", "Date posted end date") slCmd.Flags().StringP("format", "f", "json", "Response format") } diff --git a/internal/client/skiptrace.go b/internal/client/skiptrace.go index d4e26ea..43c2ca6 100644 --- a/internal/client/skiptrace.go +++ b/internal/client/skiptrace.go @@ -5,14 +5,24 @@ import ( "bytes" "encoding/json" "fmt" - "git.db.org.ai/dborg/internal/models" "io" "net/http" "net/url" + "os" "strings" + "time" + + "git.db.org.ai/dborg/internal/models" ) -func parseSSEResponse(data []byte) ([]byte, error) { +func parseSSEResponse(data []byte, debug bool) ([]byte, error) { + if debug { + fmt.Fprintln(os.Stderr, "[DEBUG] Raw SSE response:") + fmt.Fprintln(os.Stderr, "----------------------------------------") + fmt.Fprintln(os.Stderr, string(data)) + fmt.Fprintln(os.Stderr, "----------------------------------------") + } + scanner := bufio.NewScanner(bytes.NewReader(data)) const maxScanTokenSize = 10 * 1024 * 1024 @@ -21,10 +31,15 @@ func parseSSEResponse(data []byte) ([]byte, error) { var resultData []byte var foundResult bool + var events []string for scanner.Scan() { line := scanner.Text() + if debug && strings.HasPrefix(line, "event:") { + events = append(events, line) + } + if line == "event: result" { foundResult = true continue @@ -40,6 +55,11 @@ func parseSSEResponse(data []byte) ([]byte, error) { return nil, fmt.Errorf("error reading SSE response: %w", err) } + if debug { + fmt.Fprintf(os.Stderr, "[DEBUG] Events found: %v\n", events) + fmt.Fprintf(os.Stderr, "[DEBUG] Result event found: %v\n", foundResult) + } + if resultData == nil { return nil, fmt.Errorf("no result event found in SSE response") } @@ -53,11 +73,19 @@ func parseSSEResponse(data []byte) ([]byte, error) { } func (c *Client) getSSE(path string, params url.Values) ([]byte, error) { + return c.getSSEWithTimeout(path, params, 0) +} + +func (c *Client) getSSEWithTimeout(path string, params url.Values, timeout time.Duration) ([]byte, error) { fullURL := c.config.BaseURL + path if params != nil && len(params) > 0 { fullURL += "?" + params.Encode() } + if c.config.Debug { + fmt.Fprintf(os.Stderr, "[DEBUG] SSE Request: GET %s\n", fullURL) + } + req, err := http.NewRequest("GET", fullURL, nil) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) @@ -66,12 +94,22 @@ func (c *Client) getSSE(path string, params url.Values) ([]byte, error) { req.Header.Set("X-API-Key", c.config.APIKey) req.Header.Set("User-Agent", c.config.UserAgent) - resp, err := c.httpClient.Do(req) + httpClient := c.httpClient + if timeout > 0 { + httpClient = &http.Client{Timeout: timeout} + } + + resp, err := httpClient.Do(req) if err != nil { return nil, fmt.Errorf("request failed: %w", err) } defer resp.Body.Close() + if c.config.Debug { + fmt.Fprintf(os.Stderr, "[DEBUG] Response status: %d\n", resp.StatusCode) + fmt.Fprintf(os.Stderr, "[DEBUG] Content-Type: %s\n", resp.Header.Get("Content-Type")) + } + if resp.StatusCode != http.StatusOK { bodyBytes, _ := io.ReadAll(resp.Body) switch resp.StatusCode { @@ -98,7 +136,7 @@ func (c *Client) getSSE(path string, params url.Values) ([]byte, error) { contentType := resp.Header.Get("Content-Type") if strings.HasPrefix(string(data), "event:") || strings.Contains(contentType, "text/event-stream") { - return parseSSEResponse(data) + return parseSSEResponse(data, c.config.Debug) } return data, nil @@ -135,7 +173,7 @@ func (c *Client) SearchPeople(params *models.SkiptraceParams) (*models.Skiptrace func (c *Client) GetPersonReport(sxKey string, selection int) (*models.SkiptraceReportResponse, error) { path := fmt.Sprintf("/prem/skiptrace/people/report/%s/%d", sxKey, selection) - data, err := c.getSSE(path, nil) + data, err := c.getSSEWithTimeout(path, nil, 5*time.Minute) if err != nil { return nil, err } diff --git a/internal/config/config.go b/internal/config/config.go index b8538be..9df03bf 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -14,6 +14,7 @@ type Config struct { Timeout time.Duration MaxRetries int UserAgent string + Debug bool } type FileConfig struct { @@ -45,6 +46,11 @@ func (c *Config) WithAPIKey(key string) *Config { return c } +func (c *Config) WithDebug(debug bool) *Config { + c.Debug = debug + return c +} + func (c *Config) Validate() error { if c.APIKey == "" { return ErrMissingAPIKey |
