【发布时间】:2020-03-19 09:03:07
【问题描述】:
我无法使用 Express js 或 google sheet api 找到此问题的示例。我正在运行一个接收 POST 请求的快速应用程序,然后将其传递给使用 oAuth2 的函数,然后将数据作为附加行发送到谷歌表
当我调用 updateSheet() 时出现以下错误
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'installed' of undefined
at resolve (C:\Users\luther\Desktop\Pantree\index.js:50:69)
at new Promise (<anonymous>)
at authorize (C:\Users\luther\Desktop\Pantree\index.js:49:10)
at updateSheet (C:\Users\luther\Desktop\Pantree\index.js:91:28)
at app.post (C:\Users\luther\Desktop\Pantree\index.js:161:5)
at Layer.handle [as handle_request] (C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\index.js:281:22
我不知道为什么在发布时会出现此错误,因为该错误是在我的 authorize() 调用中引发的,该调用在从工作表中获取初始数据时完美运行。
我已更新 google sheet API 范围以允许读取和写入,如下所示。 我在我的资源对象中使用虚拟数据来排除正文解析器的问题,所以目前我从我的帖子请求中所做的只是调用 updateSheet() 没有参数
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];
const TOKEN_PATH = 'token.json';
// Load client secrets from a local file.
fs.readFile('client_secret.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Sheets API.
authorize(JSON.parse(content), grabSheetData);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
* @param {Object} credentials The authorization client credentials.
* @param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials) {
return new Promise(resolve => { // Added
const { client_secret, client_id, redirect_uris } = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getNewToken(oAuth2Client, e => resolve(e));
oAuth2Client.setCredentials(JSON.parse(token));
resolve(oAuth2Client);
});
});
}
/* GET SHEET DATA */
async function grabSheetData () {
var data = {
payload: ''
}
const authClient = await authorize(creds);
const request = {
spreadsheetId: 'xxxxxxxxxxxxxxxxxxxx',
range: 'A1:C',
valueRenderOption: "FORMATTED_VALUE",
dateTimeRenderOption: "SERIAL_NUMBER",
auth: authClient,
}
try {
const response = (await sheets.spreadsheets.values.get(request)).data;
console.log(JSON.stringify(response, null, 2));
data.payload=response
} catch (err) {
console.error(err);
}
return data
};
/* WRITE TO SHEET */
async function updateSheet () {
const authClient = await authorize();
const request = {
spreadsheetId: 'xxxxxxxxxxxxxxxx',
range: 'A7:C7',
valueInputOption: 'RAW',
insertDataOption: 'INSERT_ROWS',
resource: {
item: 'dummyname',
dateLogged:'dummydate',
expires:'dummy expire'
},
auth: authClient,
};
try {
const response = (await sheets.spreadsheets.values.append(request)).data;
console.log(JSON.stringify(response, null, 2));
} catch (err) {
console.error(err);
}
}
我的 app.post
app.post('/api/updateSheet', (req,res)=>{
updateSheet()
});
【问题讨论】:
-
"TypeError: Cannot read property 'installed' of undefined at resolve (C:\Users\luther\Desktop\Pantree\index.js:50:69)" 那么在线
index.js中有什么50? (和 49,基本上它周围的一切=) -
@mike-pomax-kamermans 我想这是奇怪的部分之一,因为这些行是我的 grabSheetData 函数所在的地方.....但是该函数工作正常,我知道每个函数都需要调用authorize() 使用我的令牌获得授权,但授权功能来自行:34-46
-
嗯,看起来错误发生在这一行
const { client_secret, client_id, redirect_uris } = credentials.installed;,因为credentials是undefined。credentials作为参数传递给authorize(credentials)。因此,在您可以调用授权的地方,您没有传递正确的凭据。您没有在调用authorize(credentials)的位置显示代码,因此在这方面我们无能为力。 -
这并不奇怪。请记住查看错误的含义:
UnhandledPromiseRejectionWarning表示您在某处有一个承诺,但您忘记了.catch(....):在 100% 的情况下,这肯定会导致错误,因此浏览器(和 Node)会警告您当你有一个.then(...)而没有一个.catch(...)时。在这种情况下,等待“事物”,但不要访问.data,直到等待解决并绑定到response的之后。 -
当您这样做
const authClient = await authorize(creds);时,未处理的拒绝可能发生在grabSheetData()。authorize()失败并且您在此await周围没有try/catch,因此您会收到未处理的拒绝错误。但是,根本问题是creds不是它应该的样子。您还应该在await周围有一个try/catch来捕获错误,但这不是这里的根本问题。
标签: node.js express google-sheets