来自外部 API 调用的 Firebase 函数 return 错误文本
Firebase functions return error text from external API call
我正在使用 Firebase 函数通过 Square 处理信用卡。我的功能非常适合成功的卡交易。但是,对于诸如被拒绝或不正确的 cvv 之类的卡错误,我想将该错误上下文发送给用户。我当前的代码发生了什么,我只是从云函数中收到错误 500。当我查看函数日志时,它有一个未处理的错误 { Error: Bad Request... 我可以在日志中看到所需的文本,但这不会传递到前端。这是我当前的代码。
export const processPayment = functions.https.onCall((data, context) => {
squareSetup();
const request_params = data;
const idempotency_key = crypto.randomBytes(22).toString('hex');
const payments_api = new squareConnect.PaymentsApi();
const request_body = {
source_id: request_params.nonce,
amount_money: {
amount: Math.round(request_params.amount * 100),
currency: 'USD' as squareConnect.CurrencyType
},
tip_money: {
amount: Math.round(request_params.tipAmount * 100),
currency: 'USD' as squareConnect.CurrencyType
},
idempotency_key: idempotency_key
};
return payments_api.createPayment(request_body);
});
根据api发现here。我应该得到错误类型数组的响应。但是,当我像这样在 api promise 上使用 catch
return payments_api.createPayment(request_body).catch(err => console.log(err))
不是那样的。相反,它似乎是一个完整的错误响应
{ Error: Bad Request
at Request.callback (/srv/node_modules/superagent/lib/node/index.js:706:15)
at parser (/srv/node_modules/superagent/lib/node/index.js:916:18)
at IncomingMessage.res.on (/srv/node_modules/superagent/lib/node/parsers/json.js:19:7)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
status: 400,
response:
Response {
domain:
Domain {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
members: [Array] },
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
res:
IncomingMessage {
_readableState: [Object],
readable: false,
domain: [Object],
_events: [Object],
_eventsCount: 4,
_maxListeners: undefined,
socket: [Object],
connection: [Object],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 400,
statusMessage: 'Bad Request',
client: [Object],
_consuming: true,
_dumped: false,
req: [Object],
text: '{"errors": [{"code": "CVV_FAILURE","detail": "Authorization error: \'CVV_FAILURE\'","category": "PAYMENT_METHOD_ERROR"}],"payment": {"id": "xq1y6ue6tKTZhAdbWJUwf5WHsobZY","created_at": "2020-05-19T22:45:36.408Z","updated_at": "2020-05-19T22:45:36.516Z","amount_money": {"amount": 2030,"currency": "USD"},"tip_money": {"amount": 0,"currency": "USD"},"status": "FAILED","delay_duration": "PT168H","source_type": "CARD","card_details": {"status": "FAILED","card": {"card_brand": "VISA","last_4": "1111","exp_month": 12,"exp_year": 2021,"fingerprint": "sq-1-jEohVzE5NqHD6_pF2AVfTSFbT1rRlEpA-FxCHw3ZEx1w3VgafAXvemqYf_AyJN7Dyg","card_type": "CREDIT","bin": "411111"},"entry_method": "KEYED","cvv_status": "CVV_REJECTED","avs_status": "AVS_ACCEPTED","errors": [{"code": "CVV_FAILURE","detail": "Authorization error: \'CVV_FAILURE\'","category": "PAYMENT_METHOD_ERROR"}]},"location_id": "NQYE9M4YWEVJ9","order_id": "grj0Ni4UoMVWdjhUG7NbRSWibb4F","total_money": {"amount": 2030,"currency": "USD"},"delay_action": "CANCEL","delayed_until": "2020-05-26T22:45:36.408Z"}}\n',
read: [Function] },
request:
Request {
domain: [Object],
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
_agent: false,
_formData: null,
method: 'POST',
url: 'https://connect.squareupsandbox.com/v2/payments',
_header: [Object],
header: [Object],
writable: true,
_redirects: 0,
_maxRedirects: 5,
cookies: '',
qs: {},
_query: [],
qsRaw: [],
_redirectList: [],
_streamRequest: false,
_timeout: 60000,
_responseTimeout: 0,
_data: [Object],
req: [Object],
protocol: 'https:',
host: 'connect.squareupsandbox.com',
_endCalled: true,
_callback: [Function],
res: [Object],
response: [Circular],
called: true },
req:
ClientRequest {
domain: [Object],
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 203,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'POST /v2/payments HTTP/1.1\r\nHost: connect.squareupsandbox.com\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Square-Connect-Javascript/3.20200422.1\r\nAuthorization: Bearer EAAAEP4ScCd1MuybJhfZaTDovR_0KG06LwxrKdREpSnKhNUZ2_3T0kH0AcUycdgI\r\nSquare-Version: 2020-04-22\r\nContent-Type: application/json\r\nAccept: application/json\r\nContent-Length: 203\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'POST',
path: '/v2/payments',
_ended: true,
res: [Object],
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
我可以在 属性 调用的文本下看到来自 api 的预期错误响应,但我不确定如何向下钻取到该数据
您需要按照 documentation:
中的说明处理错误
To ensure the client gets useful error details, return errors from a
callable by throwing (or returning a Promise rejected with) an
instance of functions.https.HttpsError
.
因此,在您的情况下,您应该执行以下操作(我假设 createPayment()
方法 returns 是一个 Promise):
export const processPayment = functions.https.onCall((data, context) => {
//...
return payments_api.createPayment(request_body)
.catch(error => {
throw new functions.https.HttpsError('<error-code>', '....');
})
});
可能的错误代码列表是 here。
您会发现here,一些关于如何在客户端处理错误的示例。
通过简单地向下钻取
,我能够得到预期的响应
return payments_api.createPayment(request_body).catch((err) => console.log(err.response.text));
我正在使用 Firebase 函数通过 Square 处理信用卡。我的功能非常适合成功的卡交易。但是,对于诸如被拒绝或不正确的 cvv 之类的卡错误,我想将该错误上下文发送给用户。我当前的代码发生了什么,我只是从云函数中收到错误 500。当我查看函数日志时,它有一个未处理的错误 { Error: Bad Request... 我可以在日志中看到所需的文本,但这不会传递到前端。这是我当前的代码。
export const processPayment = functions.https.onCall((data, context) => {
squareSetup();
const request_params = data;
const idempotency_key = crypto.randomBytes(22).toString('hex');
const payments_api = new squareConnect.PaymentsApi();
const request_body = {
source_id: request_params.nonce,
amount_money: {
amount: Math.round(request_params.amount * 100),
currency: 'USD' as squareConnect.CurrencyType
},
tip_money: {
amount: Math.round(request_params.tipAmount * 100),
currency: 'USD' as squareConnect.CurrencyType
},
idempotency_key: idempotency_key
};
return payments_api.createPayment(request_body);
});
根据api发现here。我应该得到错误类型数组的响应。但是,当我像这样在 api promise 上使用 catch
return payments_api.createPayment(request_body).catch(err => console.log(err))
不是那样的。相反,它似乎是一个完整的错误响应
{ Error: Bad Request
at Request.callback (/srv/node_modules/superagent/lib/node/index.js:706:15)
at parser (/srv/node_modules/superagent/lib/node/index.js:916:18)
at IncomingMessage.res.on (/srv/node_modules/superagent/lib/node/parsers/json.js:19:7)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
status: 400,
response:
Response {
domain:
Domain {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
members: [Array] },
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
res:
IncomingMessage {
_readableState: [Object],
readable: false,
domain: [Object],
_events: [Object],
_eventsCount: 4,
_maxListeners: undefined,
socket: [Object],
connection: [Object],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 400,
statusMessage: 'Bad Request',
client: [Object],
_consuming: true,
_dumped: false,
req: [Object],
text: '{"errors": [{"code": "CVV_FAILURE","detail": "Authorization error: \'CVV_FAILURE\'","category": "PAYMENT_METHOD_ERROR"}],"payment": {"id": "xq1y6ue6tKTZhAdbWJUwf5WHsobZY","created_at": "2020-05-19T22:45:36.408Z","updated_at": "2020-05-19T22:45:36.516Z","amount_money": {"amount": 2030,"currency": "USD"},"tip_money": {"amount": 0,"currency": "USD"},"status": "FAILED","delay_duration": "PT168H","source_type": "CARD","card_details": {"status": "FAILED","card": {"card_brand": "VISA","last_4": "1111","exp_month": 12,"exp_year": 2021,"fingerprint": "sq-1-jEohVzE5NqHD6_pF2AVfTSFbT1rRlEpA-FxCHw3ZEx1w3VgafAXvemqYf_AyJN7Dyg","card_type": "CREDIT","bin": "411111"},"entry_method": "KEYED","cvv_status": "CVV_REJECTED","avs_status": "AVS_ACCEPTED","errors": [{"code": "CVV_FAILURE","detail": "Authorization error: \'CVV_FAILURE\'","category": "PAYMENT_METHOD_ERROR"}]},"location_id": "NQYE9M4YWEVJ9","order_id": "grj0Ni4UoMVWdjhUG7NbRSWibb4F","total_money": {"amount": 2030,"currency": "USD"},"delay_action": "CANCEL","delayed_until": "2020-05-26T22:45:36.408Z"}}\n',
read: [Function] },
request:
Request {
domain: [Object],
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
_agent: false,
_formData: null,
method: 'POST',
url: 'https://connect.squareupsandbox.com/v2/payments',
_header: [Object],
header: [Object],
writable: true,
_redirects: 0,
_maxRedirects: 5,
cookies: '',
qs: {},
_query: [],
qsRaw: [],
_redirectList: [],
_streamRequest: false,
_timeout: 60000,
_responseTimeout: 0,
_data: [Object],
req: [Object],
protocol: 'https:',
host: 'connect.squareupsandbox.com',
_endCalled: true,
_callback: [Function],
res: [Object],
response: [Circular],
called: true },
req:
ClientRequest {
domain: [Object],
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 203,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'POST /v2/payments HTTP/1.1\r\nHost: connect.squareupsandbox.com\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Square-Connect-Javascript/3.20200422.1\r\nAuthorization: Bearer EAAAEP4ScCd1MuybJhfZaTDovR_0KG06LwxrKdREpSnKhNUZ2_3T0kH0AcUycdgI\r\nSquare-Version: 2020-04-22\r\nContent-Type: application/json\r\nAccept: application/json\r\nContent-Length: 203\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'POST',
path: '/v2/payments',
_ended: true,
res: [Object],
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
我可以在 属性 调用的文本下看到来自 api 的预期错误响应,但我不确定如何向下钻取到该数据
您需要按照 documentation:
中的说明处理错误To ensure the client gets useful error details, return errors from a callable by throwing (or returning a Promise rejected with) an instance of
functions.https.HttpsError
.
因此,在您的情况下,您应该执行以下操作(我假设 createPayment()
方法 returns 是一个 Promise):
export const processPayment = functions.https.onCall((data, context) => {
//...
return payments_api.createPayment(request_body)
.catch(error => {
throw new functions.https.HttpsError('<error-code>', '....');
})
});
可能的错误代码列表是 here。
您会发现here,一些关于如何在客户端处理错误的示例。
通过简单地向下钻取
,我能够得到预期的响应return payments_api.createPayment(request_body).catch((err) => console.log(err.response.text));