Skip to content

Commit 9efd11d

Browse files
Log analyze errors for HuggingFace analyzer
Thread ctx through HuggingFace analyzer's request chain, log every failure at origin.
1 parent e1f9e5d commit 9efd11d

1 file changed

Lines changed: 30 additions & 13 deletions

File tree

pkg/analyzer/analyzers/huggingface/huggingface.go

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ type Analyzer struct {
3030

3131
func (Analyzer) Type() analyzers.AnalyzerType { return analyzers.AnalyzerTypeHuggingFace }
3232

33-
func (a Analyzer) Analyze(_ context.Context, credInfo map[string]string) (*analyzers.AnalyzerResult, error) {
33+
func (a Analyzer) Analyze(ctx context.Context, credInfo map[string]string) (*analyzers.AnalyzerResult, error) {
3434
key, ok := credInfo["key"]
3535
if !ok || key == "" {
36-
return nil, analyzers.NewAnalysisError(a.Type().String(), analyzers.OperationValidateCredentials, analyzers.ServiceConfig, "", fmt.Errorf("key not found in credentialInfo"))
36+
err := fmt.Errorf("key not found in credentialInfo")
37+
ctx.Logger().Error(err, "huggingface credentials missing key")
38+
return nil, analyzers.NewAnalysisError(a.Type().String(), analyzers.OperationValidateCredentials, analyzers.ServiceConfig, "", err)
3739
}
3840

39-
info, err := AnalyzePermissions(a.Cfg, key)
41+
info, err := AnalyzePermissions(ctx, a.Cfg, key)
4042
if err != nil {
4143
return nil, analyzers.NewAnalysisError(a.Type().String(), analyzers.OperationAnalyzePermissions, analyzers.ServiceAPI, "", err)
4244
}
@@ -309,13 +311,14 @@ type Model struct {
309311

310312
// getModelsByAuthor calls the HF API /models endpoint with the author query param
311313
// returns a list of models and an error
312-
func getModelsByAuthor(cfg *config.Config, key string, author string) ([]Model, error) {
314+
func getModelsByAuthor(ctx context.Context, cfg *config.Config, key string, author string) ([]Model, error) {
313315
var modelsJSON []Model
314316

315317
// create a new request
316318
client := analyzers.NewAnalyzeClient(cfg)
317-
req, err := http.NewRequest("GET", "https://huggingface.co/api/models", nil)
319+
req, err := http.NewRequestWithContext(ctx, "GET", "https://huggingface.co/api/models", nil)
318320
if err != nil {
321+
ctx.Logger().Error(err, "failed to create huggingface models request", "author", author)
319322
return modelsJSON, err
320323
}
321324

@@ -330,28 +333,37 @@ func getModelsByAuthor(cfg *config.Config, key string, author string) ([]Model,
330333
// send the request
331334
resp, err := client.Do(req)
332335
if err != nil {
336+
ctx.Logger().Error(err, "failed to send huggingface models request", "author", author)
333337
return modelsJSON, err
334338
}
335339

336340
// defer the response body closing
337341
defer func() { _ = resp.Body.Close() }()
338342

343+
if resp.StatusCode != http.StatusOK {
344+
err := fmt.Errorf("unexpected status code: %d while fetching models for author %s", resp.StatusCode, author)
345+
ctx.Logger().Error(err, "unexpected status code while fetching huggingface models", "author", author, "status_code", resp.StatusCode)
346+
return modelsJSON, err
347+
}
348+
339349
// read response
340350
if err := json.NewDecoder(resp.Body).Decode(&modelsJSON); err != nil {
351+
ctx.Logger().Error(err, "failed to decode huggingface models response", "author", author)
341352
return modelsJSON, err
342353
}
343354
return modelsJSON, nil
344355
}
345356

346357
// getTokenInfo calls the HF API /whoami-v2 endpoint to get the token info
347358
// returns the token info, a boolean indicating token validity, and an error
348-
func getTokenInfo(cfg *config.Config, key string) (HFTokenJSON, bool, error) {
359+
func getTokenInfo(ctx context.Context, cfg *config.Config, key string) (HFTokenJSON, bool, error) {
349360
var tokenJSON HFTokenJSON
350361

351362
// create a new request
352363
client := analyzers.NewAnalyzeClient(cfg)
353-
req, err := http.NewRequest("GET", "https://huggingface.co/api/whoami-v2", nil)
364+
req, err := http.NewRequestWithContext(ctx, "GET", "https://huggingface.co/api/whoami-v2", nil)
354365
if err != nil {
366+
ctx.Logger().Error(err, "failed to create huggingface whoami request")
355367
return tokenJSON, false, err
356368
}
357369

@@ -361,11 +373,13 @@ func getTokenInfo(cfg *config.Config, key string) (HFTokenJSON, bool, error) {
361373
// send the request
362374
resp, err := client.Do(req)
363375
if err != nil {
376+
ctx.Logger().Error(err, "failed to send huggingface whoami request")
364377
return tokenJSON, false, err
365378
}
366379

367380
// check if the response is 200
368381
if resp.StatusCode != 200 {
382+
ctx.Logger().Error(fmt.Errorf("invalid/revoked huggingface access token"), "huggingface token invalid while fetching whoami", "status_code", resp.StatusCode)
369383
return tokenJSON, false, nil
370384
}
371385

@@ -374,6 +388,7 @@ func getTokenInfo(cfg *config.Config, key string) (HFTokenJSON, bool, error) {
374388

375389
// read response
376390
if err := json.NewDecoder(resp.Body).Decode(&tokenJSON); err != nil {
391+
ctx.Logger().Error(err, "failed to decode huggingface whoami response")
377392
return tokenJSON, true, err
378393
}
379394
return tokenJSON, true, nil
@@ -384,28 +399,30 @@ type SecretInfo struct {
384399
Models []Model
385400
}
386401

387-
func AnalyzePermissions(cfg *config.Config, key string) (*SecretInfo, error) {
402+
func AnalyzePermissions(ctx context.Context, cfg *config.Config, key string) (*SecretInfo, error) {
388403
// get token info
389-
token, success, err := getTokenInfo(cfg, key)
404+
token, success, err := getTokenInfo(ctx, cfg, key)
390405
if err != nil {
391406
return nil, err
392407
}
393408

394409
if !success {
395-
return nil, fmt.Errorf("invalid HuggingFace Access Token")
410+
err := fmt.Errorf("invalid HuggingFace Access Token")
411+
ctx.Logger().Error(err, "huggingface access token validation failed")
412+
return nil, err
396413
}
397414

398415
// get all models by username
399416
var allModels []Model
400-
userModels, err := getModelsByAuthor(cfg, key, token.Username)
417+
userModels, err := getModelsByAuthor(ctx, cfg, key, token.Username)
401418
if err != nil {
402419
return nil, err
403420
}
404421
allModels = append(allModels, userModels...)
405422

406423
// get all models from all orgs
407424
for _, org := range token.Orgs {
408-
orgModels, err := getModelsByAuthor(cfg, key, org.Name)
425+
orgModels, err := getModelsByAuthor(ctx, cfg, key, org.Name)
409426
if err != nil {
410427
return nil, err
411428
}
@@ -420,7 +437,7 @@ func AnalyzePermissions(cfg *config.Config, key string) (*SecretInfo, error) {
420437

421438
// AnalyzeAndPrintPermissions prints the permissions of a HuggingFace API key
422439
func AnalyzeAndPrintPermissions(cfg *config.Config, key string) {
423-
info, err := AnalyzePermissions(cfg, key)
440+
info, err := AnalyzePermissions(context.Background(), cfg, key)
424441
if err != nil {
425442
color.Red("[x] Error: %s", err.Error())
426443
return

0 commit comments

Comments
 (0)