gh-gei
gh-gei copied to clipboard
Better error message when IdP cannot be found
If a customer attempts to run create-team with an IdP group set, but their GitHub org is not EMU-enabled, or that specific group doesn't exist in the IdP, the CLI will crash with an unhelpful error message (in non-verbose mode it will just be our generic "An error has occurred").
We should give a more useful error message, letting the user know that they shouldn't be trying to link to IdP groups in non-EMU orgs, or that their specified IdP group can't be found.
[11:45 AM] [DEBUG] HTTP GET: https://raw.githubusercontent.com/github/gh-gei/main/LATEST-VERSION.txt
[11:45 AM] [DEBUG] RESPONSE (OK): v0.26
[11:45 AM] [INFO] You are running the latest version of the ado2gh CLI [v0.26]
[11:45 AM] [INFO] Creating GitHub team...
[11:45 AM] [INFO] GITHUB ORG: mickey-test-migrations
[11:45 AM] [INFO] TEAM NAME: MyShuttle-Maintainers
[11:45 AM] [INFO] IDP GROUP: MyShuttle-Maintainers
[11:45 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/teams
[11:45 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB8CF8:19F859B:6329EE41
[11:45 AM] [DEBUG] RESPONSE (OK): [{"name":"MyShuttle-Maintainers","id":6656283,"node_id":"T_kwDOBsS6Ms4AZZEb","slug":"myshuttle-maintainers","description":null,"privacy":"closed","url":"https://api.github.com/organizations/113556018/team/6656283","html_url":"https://github.com/orgs/mickey-test-migrations/teams/myshuttle-maintainers","members_url":"https://api.github.com/organizations/113556018/team/6656283/members{/member}","repositories_url":"https://api.github.com/organizations/113556018/team/6656283/repos","permission":"pull","parent":null}]
[11:45 AM] [INFO] Team 'MyShuttle-Maintainers' already exists - New team will not be created
[11:45 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/teams
[11:45 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB8D50:19F864F:6329EE41
[11:45 AM] [DEBUG] RESPONSE (OK): [{"name":"MyShuttle-Maintainers","id":6656283,"node_id":"T_kwDOBsS6Ms4AZZEb","slug":"myshuttle-maintainers","description":null,"privacy":"closed","url":"https://api.github.com/organizations/113556018/team/6656283","html_url":"https://github.com/orgs/mickey-test-migrations/teams/myshuttle-maintainers","members_url":"https://api.github.com/organizations/113556018/team/6656283/members{/member}","repositories_url":"https://api.github.com/organizations/113556018/team/6656283/repos","permission":"pull","parent":null}]
[11:45 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/teams/myshuttle-maintainers/members?per_page=100
[11:45 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB8D83:19F86AF:6329EE41
[11:45 AM] [DEBUG] RESPONSE (OK): [{"login":"mickeygousset","id":20031479,"node_id":"MDQ6VXNlcjIwMDMxNDc5","avatar_url":"https://avatars.githubusercontent.com/u/20031479?v=4","gravatar_id":"","url":"https://api.github.com/users/mickeygousset","html_url":"https://github.com/mickeygousset","followers_url":"https://api.github.com/users/mickeygousset/followers","following_url":"https://api.github.com/users/mickeygousset/following{/other_user}","gists_url":"https://api.github.com/users/mickeygousset/gists{/gist_id}","starred_url":"https://api.github.com/users/mickeygousset/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mickeygousset/subscriptions","organizations_url":"https://api.github.com/users/mickeygousset/orgs","repos_url":"https://api.github.com/users/mickeygousset/repos","events_url":"https://api.github.com/users/mickeygousset/events{/privacy}","received_events_url":"https://api.github.com/users/mickeygousset/received_events","type":"User","site_admin":true}]
[11:45 AM] [DEBUG] HTTP DELETE: https://api.github.com/orgs/mickey-test-migrations/teams/myshuttle-maintainers/memberships/mickeygousset
[11:45 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB8DCE:19F8752:6329EE41
[11:45 AM] [DEBUG] RESPONSE (NoContent):
[11:45 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/external-groups
[11:45 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB8E3B:19F884A:6329EE42
[11:45 AM] [DEBUG] RESPONSE (BadRequest): {"message":"This organization is not part of externally managed enterprise.","documentation_url":"https://docs.github.com/rest/reference/teams#list-external-idp-groups-for-an-organization"}
[11:45 AM] [DEBUG] Call failed with HTTP BadRequest, retrying...
[11:45 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/external-groups
[11:45 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB8FE3:19F8B94:6329EE43
[11:45 AM] [DEBUG] RESPONSE (BadRequest): {"message":"This organization is not part of externally managed enterprise.","documentation_url":"https://docs.github.com/rest/reference/teams#list-external-idp-groups-for-an-organization"}
[11:45 AM] [DEBUG] Call failed with HTTP BadRequest, retrying...
[11:45 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/external-groups
[11:45 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB92F0:19F91B9:6329EE45
[11:45 AM] [DEBUG] RESPONSE (BadRequest): {"message":"This organization is not part of externally managed enterprise.","documentation_url":"https://docs.github.com/rest/reference/teams#list-external-idp-groups-for-an-organization"}
[11:45 AM] [DEBUG] Call failed with HTTP BadRequest, retrying...
[11:46 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/external-groups
[11:46 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB97B4:19F9B88:6329EE48
[11:46 AM] [DEBUG] RESPONSE (BadRequest): {"message":"This organization is not part of externally managed enterprise.","documentation_url":"https://docs.github.com/rest/reference/teams#list-external-idp-groups-for-an-organization"}
[11:46 AM] [DEBUG] Call failed with HTTP BadRequest, retrying...
[11:46 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/external-groups
[11:46 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CB9F7D:19FAB49:6329EE4C
[11:46 AM] [DEBUG] RESPONSE (BadRequest): {"message":"This organization is not part of externally managed enterprise.","documentation_url":"https://docs.github.com/rest/reference/teams#list-external-idp-groups-for-an-organization"}
[11:46 AM] [DEBUG] Call failed with HTTP BadRequest, retrying...
[11:46 AM] [DEBUG] HTTP GET: https://api.github.com/orgs/mickey-test-migrations/external-groups
[11:46 AM] [DEBUG] GITHUB REQUEST ID: E4DB:5466:CBA83D:19FBD16:6329EE51
[11:46 AM] [DEBUG] RESPONSE (BadRequest): {"message":"This organization is not part of externally managed enterprise.","documentation_url":"https://docs.github.com/rest/reference/teams#list-external-idp-groups-for-an-organization"}
[11:46 AM] [ERROR] System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at OctoshiftCLI.GithubClient.SendAsync(HttpMethod httpMethod, String url, Object body, HttpStatusCode status, Dictionary`2 customHeaders)
at OctoshiftCLI.GithubClient.<>c__DisplayClass5_0.<<GetAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Polly.Retry.AsyncRetryEngine.ImplementationAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicates`1 shouldRetryResultPredicates, Func`5 onRetryAsync, Int32 permittedRetryCount, IEnumerable`1 sleepDurationsEnumerable, Func`4 sleepDurationProvider, Boolean continueOnCapturedContext)
at Polly.AsyncPolicy.ExecuteAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, Boolean continueOnCapturedContext)
at OctoshiftCLI.RetryPolicy.HttpRetry[T](Func`1 func, Func`2 filter)
at OctoshiftCLI.GithubClient.GetAsync(String url, Dictionary`2 customHeaders)
at OctoshiftCLI.GithubApi.GetIdpGroupId(String org, String groupName)
at OctoshiftCLI.Commands.CreateTeamCommandBase.Handle(String githubOrg, String teamName, String idpGroup, String githubPat, Boolean verbose)
at System.CommandLine.Invocation.CommandHandler.GetExitCodeAsync(Object value, InvocationContext context)
at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass23_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass27_0.<<UseVersionOption>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass25_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__24_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass11_0.<<UseDebugDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__10_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass14_0.<<UseExceptionHandler>b__0>d.MoveNext()
Would it make sense to fix this upstream in the API if possible?
In this case I think the upstream API error message is pretty good. It fails when we try to get the list of IdP groups linked to the org with the error "This organization is not part of externally managed enterprise" (i.e. this isn't an EMU org).
IMO the onus is on the CLI to translate that into a more relevant error message based on what the CLI is trying to do.