- 投稿日:2021-08-27T19:49:19+09:00
CentOS 7 で Node.js(バイナリアーカイブ)を使えるようにする方法
環境 Windows10 + Virtual Box + CentOS 7 VScode + Remote-SSH ソース入手 下記のページからダウンロードする。今回は、Linux Binaries (x64) を選択。 nodejs download page ダウンロードした node-v14.17.5-linux-x64.tar.xz を /root に移動 解凍と配置 # tar -xJvf node-v14.17.5-linux-x64.tar.xz -C /usr/local/lib/ # cd /usr/local/lib/ # ln -s node-v14.17.5-linux-x64/ nodejs パスを通す /etc/profile を編集してもよさそうだが、記述が煩雑になりそうだったので .bash_profile を編集することにする。 # vi ~/.bash_profile ... PATH=$PATH:/usr/local/lib/nodejs/bin export PATH (ZZ) # source .bash_profile # node -v v14.17.5 上記の方法は、個別ユーザーごとに /home/[user]/.bash_profile の編集が必要。 nodejs をバージョンアップする 目的のバージョンのバイナリアーカイブを入手して 解凍、/usr/local/lib/ に配置して、シンボリックリンクを張り替える。 # cd /usr/local/lib/ # rm nodejs ← rm nodejs/ 末尾にスラッシュがあるとリンク先まで削除してしまうので注意 # ln -s node-[v14.17.5]-[linux-x64] 削除 パスの記述を削除する # vi ~/.bash_profile ... PATH=$PATH:/usr/local/lib/nodejs/bin ← この行を削除 export PATH (ZZ) # source .bash_profile ディレクトリを削除する # cd /usr/local/lib/ # rm -rf node-v14.17.5-linux-x64 # rm nodejs まとめ シンボリックリンクは使える!(ネストしない限り)
- 投稿日:2021-08-27T18:51:26+09:00
サービス化したNode.jsアプリ自身にアップデート+再起動させる
やりたいこと winser を使ってWindowsサービス化したNode.jsアプリケーションをバージョンアップして再起動したい プロセスマネージャとかコンテナとかを使わずにアプリケーション自身で上記を行う(トリガは開発者が行う) Node.jsのバージョンは12.xを使用 やったこと 準備 更新が必要なファイルをリストアップした設定ファイルを作っておく。 update.json { "files": [ "package.json", "index.js" ] } バージョンアップ nodegit を使って、Gitリポジトリにあるソースコードを一時フォルダにクローンする index.js const Git = require('nodegit').Clone; const TEMP_DIR = __dirname + '/temp; await Git.clone('path/to/repo', TEMP_DIR); 一時フォルダにあるファイルから必要なファイルをコピーする( fs-extra を使用 ) index.js const files = require(TEMP_DIR + '/update.json').files; const fs = require('fs-extra'); for (const file of files) { fs.copySync(TEMP_DIR + '/' + file, __dirname + '/' + file, { overwrite: true }); } 再起動 サービスの停止と起動を実行するコマンドをバッチファイルにしておく restart.bat call net stop %1 call npm install call net start %1 exit child_process で再起動するためのコマンドを実行する。start コマンドを使ってさらに別のプロセスとしてサービスの停止~起動を実行するのがポイント index.js const { spawnSync } = require('child_process'); const serviceName = require(__dirname + '/package.json').name; spawnSync('start', ['""', 'restart.bat', `"${serviceName}"`], { stdio: 'ignore', shell: true });
- 投稿日:2021-08-27T14:29:06+09:00
【Node.js】サーバーサイドディレクトリ構成について可能な範囲でクリーンアーキテクチャっぽくしてみた
株式会社Another works CTOの塩原です。 弊社では、現在Node.jsを使ったgRPCサーバーを構築しています。 その中で、現段階でのサーバーサイドアプリケーションのディレクトリ構成を公開したいと思います! 環境 gRPC Node.js version 14系 Typescript 主なディレクトリー構成図 弊社ではmonorepoを採用しているので、.protoファイルを別ディレクトリーで管理しています。 層としてはapplication, domain, infraの三層構造となっています。 PROJECT |- grpc_proto/ |- project_a/ |- gen/ - XXX_pb.d.ts - XXX_grpc_pb.js - XXX_pb.js |-src/ |- application/ |- controller/ |- converter/ |- grpc/ |- helper/ |- consts/ # 定数ファイルをまとめたディレクトリ。どの層からも使うことができる |- domain/ |- converter/ |- entity/ |- model/ |- repository/ |- service/ |- infra/ |- s3/ |- datasource/ |- entity/ |- S3Client.ts Application層 主に、client側との接点を持つ層。 protoで生成されたクラスはこの層だけが使うことができる grpc エンドポイントごとに作成。 serviceを読んだりする処理などは、controller層で行う。 このディレクトリでは、リクエストを受け取って、レスポンスを返すといった薄い役割のみにしている controller grpcのエンドポイントと一対一でクラスを実装する。 serviceクラスを複数実行したり、domainクラスをレスポンス用の型に変換するために、converterを実行したりする。 domain層との接点はこの層が持つ。 Domain層 ビジネスロジックを担当。この層では、grpcの自動生成されたコードをこの層で使うことはできない entity serviceクラスのメソッドに対する引数で複雑なものはこちらで定義する クラスは使わずinterfaceのみとなるので、typesでもいいかもしれない model いわゆるドメインモデル クラスで実装する サーバーサイドだと、データベースのテーブル型をそのままドメインモデルとすることが多いが(Railsなど)、後述するinfra層のデータアクセス先が増えることを考えて分離した repository serviceクラスから使われる。 infra層のdatasourceなどを複数組み合わせて使う。 domainモデルと一対一の関係となっていて、datasourceから返ってくるレスポンスをconverterを使ってdomainモデルに変換して、返す。 service ビジネスロジックを実装するディレクトリ。 一つのクラスにつき、一つのメソッドとしている serviceの下にドメインモデルごとにディレクトリーを切る。 一つのサービスが複数のドメインを跨ぐことはあり得るので、その場合は主になるドメインのディレクトリの中に実装する userを作成する処理の時にuser_profileというドメインモデルがあるとき同じサービスクラス内で処理する場合がある。その場合はuserが主なのでuser/以下にサービスクラスを実装する domian |- service |- user |- UserUpdateService.ts |- UserCreateService.ts export default class UserUpdateService { constructor() {} call() { // 具体的な処理 } } infra層 外部からデータを取ってくる処理はすべてこちらでwrapする 今回はS3のみだが、Redis, MySQL, 別のマイクロサービスなどなどからデータを取得する時もすべてこの層でwrapする。 データ取得先ごとにディレクトリを切り、その中にそれぞれ、datasourceとentityを作る infra |- redis |- datasource |- UserRankingRedisDataSource.ts |- entity |- UserRankingEntity.ts RedisClient.ts |- s3 |- datasource |- UserS3Datasource.ts |- MetaTagS3DataSource.ts |- entity |- UserEntity.ts |- MetaTagEntity.ts S3Client.ts entity データ取得先のレスポンスをinterfaceで定義したもの。 またdatasourceに対して、渡すパラメーターなどをinterfaceで定義することもある。 こちらもtypeでもいいかなとは思ってる datasource 外部からの取得処理を書く。 s3であれば、ある程度のファイルの種類ごとに作ったりする。 databaseから取得する際はこの中でSQLを書いたりするような処理を書く。 データフロー controller -> service controller層ではprotoから自動で生成されたモデルを扱う serviceクラスを呼び出す際に、 複雑なデータであればconverterを使って、domain側のentityに変換して渡してあげる serviceからはdomainモデルで返ってくるので、それをapplication側のconverterを使って、protoから自動生成されたモデルに変換して、grpc層に返す repository -> datasource datasourceを実行した時の返り値として、infra層のentityが返ってくるため、converterを使ってdomainモデルに変換をおこなう。 まとめ 今回意識したポイントとして、外部の層と接点を持つ役割を各層一つにするということを意識しました。 application層ならcontroller, domain層ならrepositoryみたいな converterをいろんなところから呼ばれるとデータ変換がいろんなところで行われてしまうので、それを避けるために、ルートにおかず、層の中に閉じ込めました。 まだまだ、設計で気になる部分はあるので、逐次アップデートを続けていきます。 ▼複業でスキルを活かしてみませんか?複業クラウドの登録はこちら! https://talent.aw-anotherworks.com/?login_type=none
- 投稿日:2021-08-27T13:13:39+09:00
【Node.js】HummusJSで既存のPDFへ簡単書き込み
入力フォームのような体裁のPDFってありますよね。 例えば、こんなのです。 出典:医療費控除の明細書など -- 国税庁ホームページ-明細書・計算明細書等 直接このフォームに文字列を追記できたらペンを持たなくて済むので便利ですね! そこで利用するのがHummusJSです! 動作環境 node: v14.17.4 npm: v6.14.14 nodeやnpmの環境がない場合はインストールしてください。 HummusJSはv1.0.110を利用しました。 試してみよう プロジェクト作成 > npm init 表示される内容がよくわからなければ、全てエンターキーで飛ばして頂いて構いません。 npmでHummusJSをインストール > npm install hummus 同ディレクトリに以下ファイルを作成 overwrite.js const hummus = require("hummus"); const pdfWriter = hummus.createWriterToModify( "original.pdf", // 編集元PDFのパス { modifiedFilePath: "output.pdf" } // 保存先パス ); // フォントファイルをインポート const font = pdfWriter.getFontForFile("font.ttf"); // 編集するページを取得(1ページ目を編集するため、2つ目の引数を0とする) const pageModifier = new hummus.PDFPageModifier(pdfWriter,0); pageModifier.startContext().getContext().writeText( "野比のび太", // 入力文字列 59,572, // 座標を入力 ページの左下端が(0,0) { font: font, // フォントの指定 size: 12, // 文字サイズの指定 colorspace: "gray", // 色空間を"gray", "cmyk", "rgb"から選択 color: 0x00 // カラーコード } ); pageModifier.startContext().getContext().writeText( "ドラえもん", 59,552, { font: font, size: 12, colorspace: "rgb", color: 0x153ed3 // 青色 } ); pageModifier.endContext().writePage(); pdfWriter.end(); 同ディレクトリにinput.pdfとfont.ttfを配置 今回、input.pdfとして前述のPDF、font.ttfとして源真ゴシックをお借りしました。 実行 > node overwrite.js 正常動作した場合、何も表示されません。output.pdfが出力されます。 output.pdfの内容確認 二人の名前を氏名欄に書き込むことができました! まとめ 座標を指定しなければならないのは面倒ですが、特に難しいこともなくPDFへの書き込みをできるHummusJSを是非活用してみてください! 今回利用したコードはこちらにもあります。 参考URL HummusJS - wiki
- 投稿日:2021-08-27T13:13:39+09:00
【Node.js】HummusJSでPDFへ簡単書き込み
入力フォームのような体裁のPDFってありますよね。 例えば、こんなのです。 出典:医療費控除の明細書など -- 国税庁ホームページ-明細書・計算明細書等 直接このフォームに文字列を追記できたらペンを持たなくて済むので便利ですね! そこで利用するのがHummusJSです! 動作環境 node: v14.17.4 npm: v6.14.14 nodeやnpmの環境がない場合はインストールしてください。 HummusJSはv1.0.110を利用しました。 試してみよう プロジェクト作成 > npm init 表示される内容がよくわからなければ、全てエンターキーで飛ばして頂いて構いません。 npmでHummusJSをインストール > npm install hummus 同ディレクトリに以下ファイルを作成 overwrite.js const hummus = require("hummus"); const pdfWriter = hummus.createWriterToModify( "original.pdf", // 編集元PDFのパス { modifiedFilePath: "output.pdf" } // 保存先パス ); // フォントファイルをインポート const font = pdfWriter.getFontForFile("font.ttf"); // 編集するページを取得(1ページ目を編集するため、2つ目の引数を0とする) const pageModifier = new hummus.PDFPageModifier(pdfWriter,0); pageModifier.startContext().getContext().writeText( "野比のび太", // 入力文字列 59,572, // 座標を入力 ページの左下端が(0,0) { font: font, // フォントの指定 size: 12, // 文字サイズの指定 colorspace: "gray", // 色空間を"gray", "cmyk", "rgb"から選択 color: 0x00 // カラーコード } ); pageModifier.startContext().getContext().writeText( "ドラえもん", 59,552, { font: font, size: 12, colorspace: "rgb", color: 0x153ed3 // 青色 } ); pageModifier.endContext().writePage(); pdfWriter.end(); 同ディレクトリにinput.pdfとfont.ttfを配置 今回、input.pdfとして前述のPDF、font.ttfとして源真ゴシックをお借りしました。 実行 > node overwrite.js 正常動作した場合、何も表示されません。output.pdfが出力されます。 output.pdfの内容確認 二人の名前を氏名欄に書き込むことができました! まとめ 座標を指定しなければならないのは面倒ですが、特に難しいこともなくPDFへの書き込みをできるHummusJSを是非活用してみてください! 今回利用したコードはこちらにもあります。 参考URL HummusJS - wiki
- 投稿日:2021-08-27T12:33:05+09:00
Laravel-echo-serverでチャットアプリを作ろうとしたらSameSiteの設定で怒られた
概要 チャット機能をつけるためにLaravel-echo-server + Redisにてソケット通信を行おうとしたところSameSiteの設定でIssueが出ていた。 無事動いたので備忘録。 チャット機能は以下を参考 Laravel Broadcasting (Laravel Echo)を試してみる 環境 Laravel Framework 6.20.32 MAMP 6.4 PHP 7.4.6 やったこと localhostのSSL設定 laravelのsame_siteの設定 laravel-echo-serverのSSL設定 接続先をhttpsへ変更 localhostのSSL設定 以下のサイトを参考。 他のやり方だと何故かうまく行かなかった。 ローカル開発環境にSSLを設定できるmkcertがめちゃくちゃ便利だった laravelのsame_siteの設定 {ルート}/session.phpで設定 session.php 'same_site' => 'lax', noneに設定すると怒られたのでlaxにしました。 Mark cross-site cookies as Secure to allow setting them in cross-site contexts laravel-echo-serverのSSL設定 laravel-echo-server.jsonをSSLに対応。 認証はMAMPの時に作成したもの。 laravel-echo-server.json "port": "6001", "protocol": "https", "socketio": {}, "secureOptions": 67108864, "sslCertPath": "/Applications/MAMP/conf/apache/keys/localhost.pem", "sslKeyPath": "/Applications/MAMP/conf/apache/keys/localhost-key.pem", 忘れずにサーバーを再起動。 laravel-echo-server start 接続先をhttpsへ変更 laravel-echoの設定を変更 bootstrap.js window.Echo = new Echo({ broadcaster: 'socket.io', host: 'https://' + window.location.hostname + ':6001' }); 忘れずにjsを更新。 npm run dev おわり これでとりあえずIssuesはなくなりました。
- 投稿日:2021-08-27T11:33:17+09:00
Node.js(axios)からDirectCloud-BOX APIでファイル一覧の取得とnode話
一連の記事の流れになります。 紙で申請を出す居酒屋店員のシフト希望と管理業務をちょっとスマートにする Node.js(axios)からDirectCloud-BOX APIでファイルのDL #linedc Node.js(axios)からDirectCloud-BOX APIでファイルアップロード 同じような書き方にはなるのですが、DirectCloudのAPIのドキュメントは注意といった記事です。 また、タイトルにあるnodeはNode.jsの話ではないです。 ファイル一覧取得を試す(GET/POST) /openapp/v1/files/index/{node}でファイルの一覧を照会できます APIリファレンス - ファイルの照会 以下のコードで実行します。前の記事で書いたように、{node}は1に指定しています。 このAPIはこの指定がないとうまく動きません。(後述) また、 このAPIはフォルダリストのAPI(/openapp/v1/folders/index/{node})と同様にドキュメント上だとGETと書いてますが、何故かPOSTも利用できます。 GETの書き方 'use strcit'; const axios = require('axios'); const BASE_URL = `https://api.directcloud.jp`; const URL = `${BASE_URL}/openapp/v1/files/index/1?lang=eng` const token = `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` const main = async () => { const res = await axios.get(URL,{ headers: { access_token: token, } }); console.log(res.data); }; main(); 何故か動くPOSTの書き方 'use strcit'; const axios = require('axios'); const FormData = require('form-data'); const BASE_URL = `https://api.directcloud.jp`; const URL = `${BASE_URL}/openapp/v1/files/index/1?lang=eng` const token = `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` const main = async () => { const bodyFormData = new FormData(); const res = await axios.post(URL, bodyFormData, { headers: { access_token: token, ...bodyFormData.getHeaders() } }); console.log(res.data); }; main(); 実行 どちらも正常に動きます。 実行するとこんな感じの内容になりました。 $ node ls.js { success: true, total: 5, lastpage: true, lists: [ { file_seq: '287745501', name: 'image.png', extension: 'png', size: '2184218', creator: 'xxxxxxxxxxxx', datetime: '2021-08-26 05:29:48', sizetext: '2.08MB' }, 省略 出来てみるとなんてことないですが、後述するように、動くまでに若干詰まりました。 node指定問題 ドキュメントのミスかAPIの設計ミスがありそうFolders API問題 このAPI扱う時にやっかいな nodeという概念があります。 フォルダの場所を示す値っぽいやつです。 FoldersのAPIは、 ドキュメントに必須と書いているのに、何故かnodeを指定しなくても使えてしまってた問題がありました。 フォルダリストの照会のドキュメントを見ると フォルダリストの紹介はnodeは必須と書いてますがなぜか無しでも動きます。 それだけだったら、まぁそういうこともあるかー優しさかなぁ?って感じだったのですが、同じようなAPIの先ほどサンプルを書いた ファイルリストの照会のほうは本当にnodeが必須っぽいです。 入り方が良くなかった可能性もありますが、どっちかに統一してほしいですね。。 "node指定必須と書いているが、node無しで動く"フォルダリストAPI ドキュメント準拠してないAPIなのか、APIにドキュメントが追いついてないのか。 完全に裏をかいてくるAPIです。 'use strcit'; const axios = require('axios'); const FormData = require('form-data'); const BASE_URL = `https://api.directcloud.jp`; const URL = `${BASE_URL}/openapp/v1/folders/index/?lang=eng` //node指定がない const token = `xxxxxxxxxxxxxxxxxxxxxxxx` const main = async () => { const bodyFormData = new FormData(); const res = await axios.post(URL, bodyFormData, { headers: { access_token: token, ...bodyFormData.getHeaders() } }); console.log(res.data); }; main(); 実行結果は正常 $ node folder.js { success: true, lists: [ { dir_seq: '38605003', node: '1', 省略 "node指定必須と書いているが、node無しで動く"と思いきや動いてくれないファイルリストAPI 完全に裏をかいてくるAPIです。と先ほど書きましたが、 さらに裏を書いてくるという。 裏の裏で表ですね。はい。 こちらはドキュメント通りにnode必須ですw 'use strcit'; const axios = require('axios'); const FormData = require('form-data'); const BASE_URL = `https://api.directcloud.jp`; const URL = `${BASE_URL}/openapp/v1/files/index/?lang=eng` //node指定がない const token = `xxxxxxxxxxxxxxxxxxxxxxxx` const main = async () => { const bodyFormData = new FormData(); const res = await axios.post(URL, bodyFormData, { headers: { access_token: token, ...bodyFormData.getHeaders() } }); console.log(res.data); }; main(); 実行結果はエラー $ node file.js { success: false, all: 'There is no required input value.', result_code: '00' } うーん、、統一するかドキュメントどうにかしてほしい。 まぁフォルダーの概念を考えるとnode指定がない場合には、ルート的な場所を表示するようにしてるってのは分かるんですけど、そのルート的な場所にはファイルは置けないってことでエラーにするようにしてるんですかね? まとめ ドキュメントが疑わしい場合もある まぁドキュメント更新とAPIの機能更新の整合性が取れないタイミングってあるのは分かるので、どこかのタイミングで改善してもらえると嬉しいなと感じました。
- 投稿日:2021-08-27T10:11:02+09:00
【備忘録】npm run startで missing scriptエラーが出た場合の対処法
npm run startの結果下記エラー発生。 どうやらstartのコマンドがpackage.jsonに記載がないことが原因らしいため、色々調べてみた。 エラー文 1 error generated. make: *** [Release/obj.target/binding/src/binding.o] Error 1 gyp ERR! build error gyp ERR! stack Error: `make` failed with exit code: 2 gyp ERR! stack at ChildProcess.onExit (/Users/●●/project/●●_web_server/node_modules/node-gyp/lib/build.js:262:23) gyp ERR! stack at ChildProcess.emit (node:events:394:28) gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12) gyp ERR! System Darwin 20.6.0 gyp ERR! command "/usr/local/Cellar/node/16.7.0/bin/node" "/Users/●●/project/●●_web_server/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library=" gyp ERR! cwd /Users/●●/project/●●_web_server/node_modules/node-sass gyp ERR! node -v v16.7.0 gyp ERR! node-gyp -v v3.8.0 gyp ERR! not ok Build failed with error code: 1 npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! node-sass@4.14.1 postinstall: `node scripts/build.js` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the node-sass@4.14.1 postinstall script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /Users/●●/.npm/_logs/2021-08-27T00_05_44_201Z-debug.log 解決策 rm -rf node_modules rm -f package-lock.json npm i npm run start こちらの記事を参考にさせていただきました。
- 投稿日:2021-08-27T09:12:58+09:00
LINE BotのNode.js SDKでプロフィール取得のメモ #linedc
userIdからプロフィールを取得したいってのをちょくちょく使うけど忘れるのでメモ SDKのサンプルコード client.getProfile()を利用します。 const profile = await client.getProfile(event.source.userId); console.log(profile); { userId: 'Ubxxxxxxxxxxxxxxxxxxxxxx', displayName: 'n0bisuke', pictureUrl: 'https://profile.line-scdn.net/ch/v2/p/xxxxxxxxxxxxxxxxxxxxxxxx/exist', statusMessage: 'こんにちは', language: 'ja' } コピペ用: リプライ 1時間でLINE BOTを作るハンズオンの記事から引用したコードです。 'use strict'; const express = require('express'); const line = require('@line/bot-sdk'); const PORT = process.env.PORT || 3000; const config = { channelSecret: '作成したBOTのチャンネルシークレット', channelAccessToken: '作成したBOTのチャンネルアクセストークン' }; const app = express(); app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない) app.post('/webhook', line.middleware(config), (req, res) => { console.log(req.body.events); Promise .all(req.body.events.map(handleEvent)) .then((result) => res.json(result)); }); const client = new line.Client(config); async function handleEvent(event) { let msg = ``; if (event.type !== 'message' || event.message.type !== 'text') { return Promise.resolve(null); } //☆ココがプロフ取得箇所 const profile = await client.getProfile(event.source.userId); console.log(profile); msg = `${profile.displayName}さんこんにちは。 あなたのユーザーIDは${profile.userId}です。` return client.replyMessage(event.replyToken, { type: 'text', text: msg //実際に返信の言葉を入れる箇所 }); } app.listen(PORT); console.log(`Server running at ${PORT}`); コピペ用: プッシュメッセージ 友達全員にメッセージを送るシンプルな送信専用LINE BOTを作る【Node.js】 #linedcの記事から引用したコードです。 ただブロードキャストだと他の人にUserIdなど送るのはあまりよくないのでPushメッセージで自分だけに送信するようにしてます。 'use strict'; const line = require('@line/bot-sdk'); const config = { channelSecret: 'チャンネルシークレット', channelAccessToken: 'チャンネルアクセストークン' }; const client = new line.Client(config); let msg = ``; //☆ココがプロフ取得箇所 const userId = `Ubxxxxxxxxxxxxxxxxxxxxxxxx`; //管理画面や他APIなどから取得しておく const profile = await client.getProfile(userId); console.log(profile); msg = `${profile.displayName}さんこんにちは。あなたのユーザーIDは${profile.userId}です。` const main = async () => { const messages = [{ type: 'text', text: msg }]; try { const res = await client.pushMessage(userId, messages); console.log(res); } catch (error) { console.log(`エラー: ${error.statusMessage}`); console.log(error.originalError.response.data); } } main(); こんな感じに なります。