質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

4266閲覧

JavaScriptでエラーをcatchできない

Awayume

総合スコア60

Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/11/29 07:33

前提・実現したいこと

discord.js(Ver13)を使用してDiscordBOTを作っています。
メンバーをBANするコマンドを作りたくて以下のように書いたのですが、
MissingPermissionなどのエラーが発生したときでも、catchされずにエラーとなってしまいます。

発生している問題・エラーメッセージ

DiscordAPIError: Missing Permissions at RequestHandler.execute (/home/runner/QueasyExcitedArraylist-1/node_modules/discord.js/src/rest/RequestHandler.js:349:13) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async RequestHandler.push (/home/runner/QueasyExcitedArraylist-1/node_modules/discord.js/src/rest/RequestHandler.js:50:14) at async GuildBanManager.create (/home/runner/QueasyExcitedArraylist-1/node_modules/discord.js/src/managers/GuildBanManager.js:143:5) { method: 'put', path: '/guilds/[サーバーID]/bans/[ユーザーID]', code: 50013, httpStatus: 403, requestData: { json: { delete_message_days: 0 }, files: [] } } DiscordAPIError

該当のソースコード

js

1//略 2 3const prefix = "BOTのプレフィックス" 4 5client.on('mesaageCreate', message =>{ 6 if (message.author.bot){ 7 return; 8 } 9 10 const args = message.content.slice(prefix.length).trim().split(' '); 11 const command = args.shift().toLowerCase(); 12 13 if (command == 'ban'){ 14 id = args[0] 15 try{ 16 message.guild.members.ban(id); 17 message.channel.send("BANしました。"); 18 } 19 catch{ 20 message.channel.send("BANに失敗しました。"); 21 } 22 } 23 //略 24});

補足情報

discord.js Ver13.3.1
Node.js Ver16.12.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Discord.jsのドキュメントのbanメソッド実行結果の返り値はPromiseです。
Promiseは非同期なのでその記述では捕まえられません。

async/await構文を併用して、下記のように変更するとtry-catchで捕まえられるようになります。

js

1// awaitはasync関数内でしか使えないので、 2// アロー関数の手前にasyncというワードを入れてasync関数を定義する 3client.on('mesaageCreate', async message =>{ 4 if (message.author.bot){ 5 return; 6 } 7 8 const args = message.content.slice(prefix.length).trim().split(' '); 9 const command = args.shift().toLowerCase(); 10 11 if (command == 'ban'){ 12 id = args[0] 13 try{ 14 // await構文を使う事によって、Promiseの状態がfulfilledになるまで待つ事が実現する 15 await message.guild.members.ban(id); 16 message.channel.send("BANしました。"); 17 } 18 catch (e) { 19 // await構文で待っているPromiseがrejectedになるとこちらに入ってくる 20 // まぁ、コンソール上にエラー理由を出したほうがよいのでとりま追加 21 console.error(e); 22 message.channel.send("BANに失敗しました。"); 23 } 24 } 25 //略 26});

Node.jsでは「HTTP通信」やハードディスクの読み書き等は遅い処理として非同期処理の先に飛ばして後で処理するような思想で動いています。
Discord.jsはDiscordというシステムに問い合わせを行いますが、
このDiscordに問い合わせがまんまHTTP通信というクソ遅い処理なのです。

従って多くの機能がPromiseインスタンスを返すと想定されます。
Promiseは非同期処理をオブジェクト指向プログラミングのテクニックで上手く処理する
Node.jsが用意している最新の非同期処理の取扱い方法になります。

Promiseasync/awaitの順番で勉強して、
きちんと使いこなせるようになるのがよいでしょう。

ただまぁ、私もPromiseを完璧に理解して使いこなせるようになるまで数週間かかりました。
上のawaitがPromiseを扱うのに絶大な力を持ってて、
async関数で有効化出来るんだよくらいの認識でとりあえず開発は続けられると思います。
気が向いたら勉強してみてください。


ではここまでの流れを追っていきます。

まずはclient.on("messageCreate", message => {})の引数メッセージ、
これは何やねんというとMessageのインスタンスを指しています。
そのプロパティ一覧にはguildがあります。

これにはGuildというリンクが指定されており、
Guildのインスタンスである事がわかります。
そして更にプロパティのmembersを見ると
GuildMemberManagerのインスタンスである事がわかります。

GuildMemberManager.banはお尻に()を付けて実行しているので、
関数・メソッドという扱いになります。
メソッド欄にありますね。

実行すると結果を返り値として受け取れるようです。
Returns: Promise <(GuildMember|User|Snowflake)>

という訳でドキュメントが古くて仕様が変わっているというような事が無ければ
返り値はPromiseであり、変わることは中々ないでしょう。

丁寧に使い方もコードで紹介されています……が、
Promiseを使っても非同期処理は非同期処理のままなので
コールバック地獄と大差のないエラーハンドリングのおまじないだらけになります。

async/await構文を使ってラッピング、ハンドリングした方が良いでしょう。

投稿2021/11/29 08:07

編集2021/11/29 08:20
miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Awayume

2021/11/29 08:11

解決できました。 詳しくありがとうございました。
guest

0

詳しくないですが、ドキュメントを見る限り非同期メソッドのようですので、try catch では例外処理できないのではないかと思います。
.ban(useroptions) | discord.js

ドキュメントの通り、catchメソッドで受けるのがいいのではないですか?

投稿2021/11/29 08:12

Lhankor_Mhy

総合スコア36140

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問