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

Bug: React Email Template throws Encoding Error #128

Open
thomaslc08 opened this issue Nov 12, 2024 · 2 comments
Open

Bug: React Email Template throws Encoding Error #128

thomaslc08 opened this issue Nov 12, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@thomaslc08
Copy link

thomaslc08 commented Nov 12, 2024

Hello,

When sending transactional emails with Plunk, in certain cases, the function fails with this message:

Invalid 'prisma_1.prisma.email.create()' invocation in
/app/packages/api/dist/controllers/v1/index.js:261:66

  258         }),
  259     },
  260 });
→ 261 const createdEmail = await prisma_1.prisma.email.create(
Error occurred during query execution:
ConnectorError(ConnectorError { user_facing_error: None, kind: QueryError(PostgresError { code: "22021", message: "invalid byte sequence for encoding \"UTF8\": 0x00", severity: "ERROR", detail: None, column: None, hint: None }), transient: false })
    at Plunk.<anonymous> (/Users/thomasleclech/Code/inscriptor/apps/server/node_modules/@plunk/node/dist/lib/Plunk.js:65:23)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/thomasleclech/Code/inscriptor/apps/server/node_modules/tslib/tslib.js:166:62)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
[Nest] 74873  - 11/12/2024, 12:25:02 PM   ERROR [ExceptionsHandler] 
Invalid 'prisma_1.prisma.email.create()' invocation in
/app/packages/api/dist/controllers/v1/index.js:261:66

  258         }),
  259     },
  260 });
→ 261 const createdEmail = await prisma_1.prisma.email.create(
Error occurred during query execution:
ConnectorError(ConnectorError { user_facing_error: None, kind: QueryError(PostgresError { code: "22021", message: "invalid byte sequence for encoding \"UTF8\": 0x00", severity: "ERROR", detail: None, column: None, hint: None }), transient: false })
Error: 
Invalid 'prisma_1.prisma.email.create()' invocation in
/app/packages/api/dist/controllers/v1/index.js:261:66

  258         }),
  259     },
  260 });
→ 261 const createdEmail = await prisma_1.prisma.email.create(`

The email does not appear to be sent on Plunk dashboard but I receive it anyway.

I'm using this function with React Email:

const emailHtml = await render(
            FiscalReceiptEmail({
              firstName: element.order?.member?.firstName || undefined,
              contactEmail: formattedTenant.settings?.fr_contactEmail,
              fiscalReceiptUrl: `${formattedTenant.settings?.fr_pdf_download_url}?id=${element.id}`,
              logoUrl: formattedTenant.logo || undefined,
              type: element.order.member ? 'individual' : 'organization',
              thankMessage: formattedTenant.settings?.fr_thankMessage,
              tenant: {
                street: formattedTenant?.address?.number
                  ? formattedTenant.address.number + ' ' + formattedTenant.address.street
                  : formattedTenant?.address?.street
                    ? formattedTenant.address.street
                    : undefined,
                city: formattedTenant?.address?.city,
                zipCode: formattedTenant?.address?.postalCode,
                name: formattedTenant?.name,
              },
            }),
          );

          const email = await plunk.emails.send({
            to: emailAddress,
            subject: 'Reçu fiscal disponible', 
            body: emailHtml,
          });`

Thank you

@driaug
Copy link
Member

driaug commented Nov 12, 2024

Could you share with me the actual React Email template, not just the function that calls it.

@driaug driaug changed the title Error: prisma.email.create Bug: React Email Template throws Encoding Error Nov 12, 2024
@thomaslc08
Copy link
Author

Here is the code for the React Email template:

import {
  Body,
  Container,
  Column,
  Head,
  Heading,
  Html,
  Img,
  Link,
  Preview,
  Row,
  Section,
  Text,
  Button,
} from '@react-email/components';
import * as React from 'react';

interface Tenant {
  name: string;
  street?: string;
  zipCode?: string;
  city?: string;
}

interface Props {
  type: 'organization' | 'individual';
  firstName?: string;
  fiscalReceiptUrl: string;
  logoUrl?: string;
  contactEmail?: string;
  thankMessage?: string;
  tenant: Tenant;
}

export const FiscalReceiptEmail = (props: Props) => (
  <Html lang="fr" >
    <Head />
    <Preview>
      {`Bonjour ${
        props.type === 'individual' && props.firstName ? props.firstName : ''
      } ! Vous avez récemment effectué un don à ${
        props.tenant.name ?? 'notre organisation'
      }, vous pouvez dès à présent télécharger votre reçu fiscal.`}
    </Preview>
    <Body style={main}>
      <Container style={container}>
        <Section style={logoContainer}>
          {props.logoUrl ? (
            <Img src={props.logoUrl} width="90" height="auto" alt="logo" />
          ) : (
            <Text style={text}>{props.tenant.name}</Text>
          )}
        </Section>
        <Heading style={h1}>{`${
          props.type === 'individual' && props.firstName
            ? `${props.firstName}, merci pour votre don !`
            : 'Merci pour votre don !'
        }`}</Heading>
        <Text style={heroText}>
          {props.thankMessage ? props.thankMessage : ''}
        </Text>

        {props.type === 'individual' && (
          <Text style={heroText}>
            En tant que particulier, votre don ouvre droit à une réduction
            d'impôt égale à 66 % du montant de votre don, dans la limite de 20 %
            de votre revenu imposable.
          </Text>
        )}
        {props.type === 'organization' && (
          <Text style={heroText}>
            En tant qu'entreprise, votre don ouvre droit à une réduction d'impôt
            sur les sociétés égale à 60 % du montant versé, avec un plafond fixé
            à 20 000 € ou à 5 ‰ (5 pour mille) du chiffre d'affaires annuel hors
            taxes de l'entreprise. Si ce plafond est dépassé, l'excédent peut
            être reporté sur les cinq exercices fiscaux suivants.
          </Text>
        )}

        <Text style={heroText}>
          À ce titre, vous pouvez dès maintenant télécharger votre reçu fiscal
          en cliquant sur le bouton ci-dessous.
        </Text>
        <Button style={button} href={props.fiscalReceiptUrl}>
          Télécharger mon reçu fiscal
        </Button>

        {props.contactEmail && (
          <Text style={text}>
            En cas d'informations incorrectes ou manquantes, vous pouvez nous
            contacter à l'adresse suivante :{' '}
            <a style={link} href={`mailto:${props.contactEmail}`}>
              {props.contactEmail}
            </a>
          </Text>
        )}

      
      </Container>
    </Body>
  </Html>
);

FiscalReceiptEmail.PreviewProps = {
  type: 'individual',
  firstName: 'Thomas',
  fiscalReceiptUrl:
    'http://localhost:3000/faire-un-don/recu-fiscal/?id=6K5m46vThmcZJ9',
  logoUrl:
    'https://res.cloudinary.com/dzj34hhvb/image/upload/v1724191002/y11pikbtlf8jqrqnyuxd.png',
  contactEmail: '[email protected]',
  tenant: {
    name: 'Test',
    address: 'BP14',
    zipCode: '29200',
    city: 'Brest',
  },
};


export default FiscalReceiptEmail;

const footerText = {
  fontSize: '12px',
  color: '#b7b7b7',
  lineHeight: '15px',
  textAlign: 'left' as const,
  marginBottom: '50px',
};

const main = {
  backgroundColor: '#ffffff',
  margin: '0 auto',
  fontFamily:
    "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
};

const container = {
  margin: '0 auto',
  padding: '0px 12px',
};

const logoContainer = {
  marginTop: '32px',
};

const h1 = {
  color: '#1d1c1d',
  fontSize: '36px',
  // fontWeight: "700",
  margin: '30px 0',
  padding: '0',
  lineHeight: '42px',
};

const button = {
  backgroundColor: '#1869A8',
  borderRadius: '9px',
  color: '#fff',
  fontSize: '18px',
  paddingTop: '19px',
  paddingBottom: '19px',
  textDecoration: 'none',
  textAlign: 'center' as const,
  display: 'block',
  width: '100%',
};

const heroText = {
  fontSize: '20px',
  lineHeight: '28px',
  marginBottom: '30px',
};

const link = {
  color: '#5f5f5f',
};

const text = {
  color: '#000',
  fontSize: '14px',
  lineHeight: '24px',
};

I ended up to add this in my code to avoid the error:

const fixedMail = emailHtml.replace(/\u0000/g, '');

@driaug driaug added the bug Something isn't working label Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants