Skip to content

Commit 01a77a8

Browse files
add debug flag for submit
1 parent 9eadd9f commit 01a77a8

File tree

3 files changed

+83
-12
lines changed

3 files changed

+83
-12
lines changed

client/lessons.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,13 @@ type lessonSubmissionCLI struct {
191191
CLIResults []CLIStepResult
192192
}
193193

194+
type SubmissionDebugData struct {
195+
Endpoint string
196+
RequestBody string
197+
ResponseStatusCode int
198+
ResponseBody string
199+
}
200+
194201
type LessonSubmissionEvent struct {
195202
ResultSlug VerificationResultSlug
196203
StructuredErrCLI *StructuredErrCLI
@@ -212,27 +219,36 @@ const (
212219
VerificationResultSlugFailure VerificationResultSlug = "failure"
213220
)
214221

215-
func SubmitCLILesson(uuid string, results []CLIStepResult) (LessonSubmissionEvent, error) {
222+
func SubmitCLILesson(uuid string, results []CLIStepResult, captureDebug bool) (LessonSubmissionEvent, SubmissionDebugData, error) {
223+
endpoint := fmt.Sprintf("/v1/lessons/%v/", uuid)
224+
debugData := SubmissionDebugData{Endpoint: endpoint}
225+
216226
bytes, err := json.Marshal(lessonSubmissionCLI{CLIResults: results})
217227
if err != nil {
218-
return LessonSubmissionEvent{}, err
228+
return LessonSubmissionEvent{}, debugData, err
219229
}
220-
endpoint := fmt.Sprintf("/v1/lessons/%v/", uuid)
230+
if captureDebug {
231+
debugData.RequestBody = string(bytes)
232+
}
233+
221234
resp, code, err := fetchWithAuthAndPayload("POST", endpoint, bytes)
235+
debugData.ResponseStatusCode = code
236+
if captureDebug {
237+
debugData.ResponseBody = string(resp)
238+
}
222239
if err != nil {
223-
return LessonSubmissionEvent{}, err
240+
return LessonSubmissionEvent{}, debugData, err
224241
}
225242
if code == 402 {
226-
return LessonSubmissionEvent{}, fmt.Errorf("to run and submit the tests for this lesson, you must have an active Boot.dev membership\nhttps://boot.dev/pricing")
243+
return LessonSubmissionEvent{}, debugData, fmt.Errorf("to run and submit the tests for this lesson, you must have an active Boot.dev membership\nhttps://boot.dev/pricing")
227244
}
228245
if code != 200 {
229-
return LessonSubmissionEvent{}, fmt.Errorf("failed to submit CLI lesson (code %v): %s", code, string(resp))
246+
return LessonSubmissionEvent{}, debugData, fmt.Errorf("failed to submit CLI lesson (code %v): %s", code, string(resp))
230247
}
231248

232249
result := LessonSubmissionEvent{}
233-
err = json.Unmarshal(resp, &result)
234-
if err != nil {
235-
return LessonSubmissionEvent{}, err
250+
if err := json.Unmarshal(resp, &result); err != nil {
251+
return LessonSubmissionEvent{}, debugData, err
236252
}
237-
return result, nil
253+
return result, debugData, nil
238254
}

cmd/run.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
func init() {
88
rootCmd.AddCommand(runCmd)
99
runCmd.Flags().BoolVarP(&forceSubmit, "submit", "s", false, "shortcut flag to submit after running")
10+
runCmd.Flags().BoolVar(&debugSubmission, "debug", false, "log submission request/response debug output")
1011
}
1112

1213
// runCmd represents the run command

cmd/submit.go

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ package cmd
33
import (
44
"errors"
55
"fmt"
6+
"os"
7+
"path/filepath"
68
"runtime"
9+
"time"
710

811
"github.com/bootdotdev/bootdev/checks"
912
api "github.com/bootdotdev/bootdev/client"
@@ -14,10 +17,14 @@ import (
1417
"github.com/spf13/viper"
1518
)
1619

17-
var forceSubmit bool
20+
var (
21+
forceSubmit bool
22+
debugSubmission bool
23+
)
1824

1925
func init() {
2026
rootCmd.AddCommand(submitCmd)
27+
submitCmd.Flags().BoolVar(&debugSubmission, "debug", false, "log submission request/response debug output")
2128
}
2229

2330
// submitCmd represents the submit command
@@ -71,7 +78,15 @@ func submissionHandler(cmd *cobra.Command, args []string) error {
7178
cliResults := checks.CLIChecks(data, overrideBaseURL, ch)
7279

7380
if isSubmit {
74-
submissionEvent, err := api.SubmitCLILesson(lessonUUID, cliResults)
81+
submissionEvent, debugData, err := api.SubmitCLILesson(lessonUUID, cliResults, debugSubmission)
82+
if debugSubmission {
83+
var debugPath string
84+
var debugWriteErr error
85+
defer func() {
86+
reportDebugFileWrite(debugPath, debugWriteErr)
87+
}()
88+
debugPath, debugWriteErr = writeSubmissionDebugFile(lessonUUID, debugData)
89+
}
7590
if err != nil {
7691
return err
7792
}
@@ -82,3 +97,42 @@ func submissionHandler(cmd *cobra.Command, args []string) error {
8297
}
8398
return nil
8499
}
100+
101+
func reportDebugFileWrite(path string, err error) {
102+
if err != nil {
103+
fmt.Fprintf(os.Stderr, "warning: failed to write submission debug output: %v\n", err)
104+
return
105+
}
106+
fmt.Fprintf(os.Stderr, "Submission debug output written to %s\n", path)
107+
}
108+
109+
func writeSubmissionDebugFile(lessonUUID string, data api.SubmissionDebugData) (string, error) {
110+
now := time.Now()
111+
timestamp := now.Format("20060102-150405")
112+
filename := fmt.Sprintf("bootdev-submit-debug-%s-%s.txt", lessonUUID, timestamp)
113+
status := "unavailable"
114+
if data.ResponseStatusCode != 0 {
115+
status = fmt.Sprintf("%d", data.ResponseStatusCode)
116+
}
117+
118+
contents := fmt.Sprintf(
119+
"bootdev submit debug\nTimestamp: %s\nLesson UUID: %s\nEndpoint: %s\n\n=== Request JSON ===\n%s\n\n=== Response ===\nStatus Code: %s\n%s\n",
120+
now.Format(time.RFC3339),
121+
lessonUUID,
122+
data.Endpoint,
123+
data.RequestBody,
124+
status,
125+
data.ResponseBody,
126+
)
127+
128+
if err := os.WriteFile(filename, []byte(contents), 0o600); err != nil {
129+
return "", err
130+
}
131+
132+
absPath, err := filepath.Abs(filename)
133+
if err != nil {
134+
return filename, nil
135+
}
136+
137+
return absPath, nil
138+
}

0 commit comments

Comments
 (0)