Remix+CloudflareでWebサイトを作る 36(複数のユニーク制約があるときのエラーハンドリング、fakerのslug、オートスケーリング、日付と時間選択フォーム)
【2024-10-14】メモ
こんなのあるんだ。使ってみたい
【2024-10-14】テーブルに複数ユニーク制約がある場合のエラーハンドリング
背景
こんなモデルがPrismaで定義されているとする。
model Sample {
id Int @id @unique @default(autoincrement())
name String @unique
url String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
name
と url
で、それぞれ重複している場合のエラーメッセージを変えたい。
export async function createSample(
client: PrismaClient,
sample: Pick<Sample, "name" | "url">
): Promise<void> {
try {
await client.sample.create({
data: {
name: sample.name,
url: sample.url,
},
});
} catch (e: any) {
if (
e instanceof Prisma.PrismaClientKnownRequestError &&
e.code === "P2002"
) {
// ここで、URLが重複している場合はエラーメッセージを変えたい
throw new Error(`名前が重複しています`);
}
throw new Error(e);
}
}
AIに聞いてみる
e.meta?.target
の中身でハンドリングする方法を提示されるがこれはうまくいかない。
というのもe.meta?.target
には [ 'UNIQUE constraint failed' ]
という値が入っているだけでカラム名は入っていない...。
export async function createSample(
client: PrismaClient,
sample: Pick<Sample, "name" | "url">
): Promise<void> {
try {
await client.sample.create({
data: {
name: sample.name,
url: sample.url,
},
});
} catch (e: any) {
// PrismaClientKnownRequestErrorでユニーク制約違反をキャッチ
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === 'P2002') {
const targetField = e.meta?.target as string[]; // 重複したフィールド名を取得
if (targetField?.includes('name')) {
throw new Error('名前が重複しています');
}
if (targetField?.includes('url')) {
throw new Error('URLが重複しています');
}
}
throw new Error(e);
}
}
なんでだ?
複数のカラムにユニーク制約があるとこうなるっぽい。
ではどうするのかAIに聞いてみる
AIにはfindUnique
を用いてカラムごとに重複チェックを行う方法を教えられた。
これだとカラム名分だけリクエストが発生しちゃうのが気になる。
あと、これそもそも新規作成のときなら良いかもだけど、更新のときに同じ様な書き方をするとバグる。
具体的には、同じ sample.name
を入力して更新ボタンを押すとエラーになってしまう。
もっとスマートな方法探さねば。
export async function createSample(
client: PrismaClient,
sample: Pick<Sample, "name" | "url">
): Promise<void> {
try {
// nameが重複しているかをチェック
const existingName = await client.sample.findUnique({
where: { name: sample.name },
});
if (existingName) {
throw new Error('名前が重複しています');
}
// url重複しているかをチェック
const existingLink = await client.sample.findUnique({
where: { link: sample.link },
});
if (existingLink) {
throw new Error('URLが重複しています');
}
await client.sample.create({
data: {
name: sample.name,
url: sample.url,
},
});
} catch (e: any) {
throw new Error(e.message || 'Sampleの作成に失敗しました');
}
}
Failed to publish your Function. Got error: Unknown internal error occurred.
【2024-10-14】エラー:GitHub Actionsでデプロイするときにたま〜〜〜〜に(1ヶ月に1回くらい?)発生するこのエラー何。
もう1回実行したら成功する場合もあれば、何回やっても無理で翌日に再実行したらうまくいった時もある。
✨ Compiled Worker successfully
Uploading... (78/112)
Uploading... (90/112)
Uploading... (101/112)
Uploading... (112/112)
✨ Success! Uploaded 34 files (78 already uploaded) (1.42 sec)
✨ Uploading Functions bundle
🌎 Deploying...
✘ [ERROR] Deployment failed!
Failed to publish your Function. Got error: Unknown internal error occurred.
faker.lorem.slug()
はfakerJA
では使えない
【2024-10-17】背景
slugを作成するためにfaker.lorem.slug({ min: 5, max: 10 })
というコードを書いたら-------
みたいなハイフン繋ぎの文字列が作成された。
原因・解決方法
fakerJA
を使っていたのが原因だった。
fakerJA.lorem.lines()
では日本語で作成できるけど、slugは英語でしか作成できないゆえに起きていることなのかな?
別に日本語でほげほげ-ふがふが
というの作成されても良い気がするけどそれはslugではないということなのか。
- import { fakerJA as faker } from "@faker-js/faker";
+ import { fakerJA as faker, fakerEN } from "@faker-js/faker";
- faker.lorem.slug({ min: 5, max: 10 })
+ fakerEN.lorem.slug({ min: 5, max: 10 })
【2024-10-17】Cloudflareにおけるオートスケーリングとかロードバランシングとか
背景
このツイートを見て「大量にリクエストきたときのオートスケーリングとかってCloudflareどうなってるんだっけ?」と思ったので調べてみる。
なんかよしなにやってくれてんの?
2022年の記事。つまりどういうことだ。
参照記事をAIに要約させよう。
この記事は、Cloudflareが紹介する「Supercloud」と呼ばれる新しいクラウドコンセプトについて説明しています。Supercloudは、従来の仮想マシン(VM)に依存するクラウドコンピューティングから進化し、コードの実行やデータの位置などの複雑な処理を自動化・効率化します。これにより、開発者はスケーリングや仮想マシンの管理を考えることなく、アプリケーションをインターネット規模で動作させることができます。
CloudflareのSupercloudは、効率的なリソース使用とコスト削減を実現し、パフォーマンス、スケーラビリティ、プライバシー、コスト効率が大幅に向上します。例えば、アプリケーションの実行は、必要なときに必要なだけ行われ、無駄なリソースの支払いを避けることができます。また、Supercloudはデータの流動性を高め、必要に応じてコードやデータがユーザーの近くで実行され、最適なパフォーマンスを提供します。
どうやらスケーリングや場所など細かいことは気にせず〜ってことが書かれているっぽいけどほんと?
自分がほしい答えをくれるとそれはそれで不安になる。
調べてちゃんと理解せねば。。
Cloudflare のLoad Balancer with EC2
Load Balancerの機能自体は別途あって、この記事ではEC2使ってやってる。
【2024-10-18】shadcnで日付と時間を選択するフォームが欲しい
公式では
これは日付を選択できるだけで、時間は選択できない。
調べよう。
shadcn/ui expansions
ここを参考にすればできそう。
MultiSelectorのときにも参考にしたところだけどまた助けてくれた...!ありがとう。。
選択肢のDropdown(上の画像でいうと「October」のところ)をクリックするとPopoverごと閉じられてしまう挙動になっているので直したい。
あと、UIもちょくちょくpadidngが足りてないところがあるので修正する。
修正したら以下のStackBllitzにコンポーネント作って、以下みたいに記事書く。