@@ -22,16 +22,24 @@ abstract class ProjectCommands {
2222 required final String projectDir,
2323 required final String configFilePath,
2424 }) async {
25- logger.init ('Creating Serverpod Cloud project "$projectId ".' );
26-
2725 // Check that the user is on a plan and automatically procure one if not.
2826 // This behavior will be changed in the future.
2927 final planNames = await cloudApiClient.plans.listProcuredPlanNames ();
3028 if (planNames.isEmpty) {
3129 const defaultPlanName = 'closed-beta' ;
32- await cloudApiClient.plans.procurePlan (planName: defaultPlanName);
30+ try {
31+ await cloudApiClient.plans.procurePlan (planName: defaultPlanName);
32+ } on ResourceDeniedException catch (e) {
33+ final setupUrl = _getConsoleSetupAccountUrl ();
34+ throw FailureException (
35+ error:
36+ "Couldn't procure the plan '$defaultPlanName ':\n ${e .message }" ,
37+ hint: 'Visit $setupUrl to set up your account.' );
38+ }
39+ logger.init ('Creating Serverpod Cloud project "$projectId ".' );
3340 logger.info ('On plan: $defaultPlanName ' );
3441 } else {
42+ logger.init ('Creating Serverpod Cloud project "$projectId ".' );
3543 logger.debug ('On plan: ${planNames .first }' );
3644 }
3745
@@ -375,4 +383,14 @@ abstract class ProjectCommands {
375383 gitIgnoreFile.writeAsStringSync ('$content $scloudIgnoreTemplate ' );
376384 return true ;
377385 }
386+
387+ static String _getConsoleSetupAccountUrl () {
388+ const prodConsoleHost = 'https://console.serverpod.cloud' ;
389+ const setupLandingPath = '/projects/create' ;
390+
391+ final hostFromEnv =
392+ Platform .environment['SERVERPOD_CLOUD_CONSOLE_SERVER_URL' ];
393+ final consoleHost = hostFromEnv ?? prodConsoleHost;
394+ return '$consoleHost $setupLandingPath ' ;
395+ }
378396}
0 commit comments