Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved astro:env errors #11381

Closed
1 task
xino1010 opened this issue Jun 30, 2024 · 7 comments · Fixed by #11455
Closed
1 task

Improved astro:env errors #11381

xino1010 opened this issue Jun 30, 2024 · 7 comments · Fixed by #11455
Assignees
Labels
- P2: nice to have Not breaking anything but nice to have (priority) feat: env related to the way astro handles `.env` or `import.meta.env` or `process.env` (scope)

Comments

@xino1010
Copy link

xino1010 commented Jun 30, 2024

Astro Info

- astro: 4.11.3
- node: 18.18.2

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

  • Use last experimental type-safe environment variables features and define an env var in astro.config.mjs.
import { defineConfig, envField } from "astro/config";

import node from "@astrojs/node";

// https://astro.build/config
export default defineConfig({
  experimental: {
    env: {
      schema: {
        ...,
        DB_PASS: envField.string({
          context: "server",
          access: "secret",
        }),
        ...,
      },
    },
  },
  output: "server",
  adapter: node({
    mode: "standalone",
  }),
});

Use the env var, for example,src/data-source.ts.

import { DB_HOST, DB_NAME, DB_PASS, DB_PORT, DB_USER } from "astro:env/server";
import { DataSource } from "typeorm";
import { Todo } from "./entities/todo";

const dataSource: DataSource = new DataSource({
  type: "mysql",
  host: DB_HOST,
  port: DB_PORT,
  username: DB_USER,
  password: DB_PASS,
  database: DB_NAME,
  entities: [Todo],
  synchronize: true,
  logging: false,
});

export const getDataSource = async (): Promise<DataSource> => {
  if (!dataSource.isInitialized) {
    try {
      await dataSource.initialize();
    } catch (e) {
      console.error("Failed to initialize data source", e);
      process.exit(1);
    }
  }
  return dataSource;
};
  • Build the project.
npm run build
  • Launch the project.
npm run preview
  • Node throw an error
22:14:07 [ERROR] EnvInvalidVariable: The following environment variable does not match the data type and/or properties defined in `experimental.env.schema`: DB_NAME is not of type string
    at createInvalidVariableError (file:///Users/dani/git/astro-dummy/dist/server/chunks/astro/env-setup_K_VhW_hQ.mjs:134:10)
    at _internalGetSecret (file:///Users/dani/git/astro-dummy/dist/server/chunks/data-source_DM7eOVU6.mjs:66:8)
    at file:///Users/dani/git/astro-dummy/dist/server/chunks/data-source_DM7eOVU6.mjs:78:1
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

Defining the var with access public, there is not error:

import { defineConfig, envField } from "astro/config";

import node from "@astrojs/node";

// https://astro.build/config
export default defineConfig({
  experimental: {
    env: {
      schema: {
        ...,
        DB_PASS: envField.string({
          context: "server",
          access: "public",
        }),
        ...,
      },
    },
  },
  output: "server",
  adapter: node({
    mode: "standalone",
  }),
});

What's the expected result?

Launch the application without any error.

Link to Minimal Reproducible Example

https://github.com/xino1010/astro-env-example

Participation

  • I am willing to submit a pull request for this issue.
@github-actions github-actions bot added the needs triage Issue needs to be triaged label Jun 30, 2024
@florian-lefebvre
Copy link
Member

The reproduction does not show this issue, please update it

@florian-lefebvre florian-lefebvre added the needs repro Issue needs a reproduction label Jul 1, 2024
Copy link
Contributor

github-actions bot commented Jul 1, 2024

Hello @xino1010. Please provide a minimal reproduction using a GitHub repository or StackBlitz. Issues marked with needs repro will be closed if they have no activity within 3 days.

@github-actions github-actions bot removed the needs triage Issue needs to be triaged label Jul 1, 2024
@xino1010
Copy link
Author

xino1010 commented Jul 1, 2024

@florian-lefebvre here you'll find an example to reproduce the bug.

@florian-lefebvre florian-lefebvre added needs triage Issue needs to be triaged and removed needs repro Issue needs a reproduction labels Jul 2, 2024
@florian-lefebvre florian-lefebvre self-assigned this Jul 2, 2024
@florian-lefebvre
Copy link
Member

I think this is because at https://github.com/withastro/astro/blob/main/packages/integrations/node/src/server.ts#L11 (and same for vercel and netlify), process.env is not loaded with .env. Maybe we should call loadEnv? @ematipico

@ematipico
Copy link
Member

I think this is because at main/packages/integrations/node/src/server.ts#L11 (and same for vercel and netlify), process.env is not loaded with .env. Maybe we should call loadEnv? @ematipico

Should we? astro preview is meant to run a production-like server, and I doubt users will use .env to load their secrets in production. Those secrets should injected via process.env. In this particular case, the secret should be passed like this

CHAT_GPT_SECRET=123456 astro preview

@xino1010
Copy link
Author

xino1010 commented Jul 3, 2024

I think this is because at main/packages/integrations/node/src/server.ts#L11 (and same for vercel and netlify), process.env is not loaded with .env. Maybe we should call loadEnv? @ematipico

Should we? astro preview is meant to run a production-like server, and I doubt users will use .env to load their secrets in production. Those secrets should injected via process.env. In this particular case, the secret should be passed like this

CHAT_GPT_SECRET=123456 astro preview

Maybe we're talking about two different things:

  • if a variable is defined as a secret, this one should be available using types in the code.
import { defineConfig, envField } from "astro/config";

import node from "@astrojs/node";

// https://astro.build/config
export default defineConfig({
  output: "server",
  adapter: node({
    mode: "standalone",
  }),
  experimental: {
    env: {
      schema: {
        CHAT_GPT_KEY: envField.string({
          context: "server",
          access: "secret",
        }),
      },
    },
  },
});
---
import { CHAT_GPT_KEY } from "astro:env/server";
console.log(CHAT_GPT_KEY);
---
  • as I understood getSecret function can be used to get the value of an env var not defined in astro.config.mjs.

so the issue here is, in preview and build mode, the secret var is not accessible.

11:18:15 [ERROR] EnvInvalidVariable: The following environment variable does not match the data type and/or properties defined in `experimental.env.schema`: CHAT_GPT_KEY is not of type string

@florian-lefebvre
Copy link
Member

Yeah I agree errors need improvements, regarding what validation rule is failing exactly (eg. startsWith)

@florian-lefebvre florian-lefebvre added - P2: nice to have Not breaking anything but nice to have (priority) feat: env related to the way astro handles `.env` or `import.meta.env` or `process.env` (scope) and removed needs triage Issue needs to be triaged labels Jul 3, 2024
@florian-lefebvre florian-lefebvre changed the title astro:env defining an env var with server context and access secret for output server and adapter node throws EnvInvalidVariable error Improved astro:env errors Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P2: nice to have Not breaking anything but nice to have (priority) feat: env related to the way astro handles `.env` or `import.meta.env` or `process.env` (scope)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants