actualbudget / actualbudget/actual

[Bug]: Gocardless error messages are not shown in actual budget UI

Ouverte
#2,415 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
bank sync user interface
Langage dominant
TypeScript
Étoiles
28.7k
Forks
3k
Merge moyen
2 j 11 h
PR mergées (30 j)
65

Description

### Verified issue does not already exist?

- [X] I have searched and found no existing issue

### Is this related to GoCardless, Simplefin or another bank-sync provider?

- [ ] I have checked my server logs and could not see any errors there
- [ ] I will be attaching my server logs to this issue
- [X] I will be attaching my client-side (browser) logs to this issue
- [X] I understand that this issue will be automatically closed if insufficient information is provided

### What happened?

I am having issues connecting my Gocardless account and loading banks. This turned out to be an issue where my IP address of my VPS is being blocked by Gocardless and thus generating a 403 error.

It had taken a while to get to that conclusion, mostly because Actual budget did not show the gocardless 403 error in the UI.

I was attempting to add a new bank account, after entering my Gocardless API details, when choosing from the drop down tha tselects country I was expecting to see a list of bank accounts, but was instead shown the following generic error.

`Failed loading available banks: GoCardless access credentials might be misconfigured. Please set them up again.`

Looking at the browser console, showed the following:

get-banks shows a 500 error ({"status":"error","reason":"internal-error"})

looking at the server logs shows the following: 403 from Gocardless.

I think a better option would be to show a detailed error option which then shows the full error from Gocardless, rather than having to go through server logs.

### What error did you receive?

```
Error /gocardless/get-banks h [AxiosError]: Request failed with status code 403
at re (file:///app/node_modules/nordigen-node/dist/index.esm.js:13:914)
at IncomingMessage. (file:///app/node_modules/nordigen-node/dist/index.esm.js:17:16270)
at IncomingMessage.emit (node:events:529:35)
at endReadableNT (node:internal/streams/readable:1400:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: 'ERR_BAD_REQUEST',
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [ 'xhr', 'http' ],
transformRequest: [ [Function (anonymous)] ],
transformResponse: [ [Function (anonymous)] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function], Blob: [class Blob] },
validateStatus: [Function: validateStatus],
headers: T [AxiosHeaders] {
Accept: 'application/json',
'Content-Type': 'application/json',
'User-Agent': 'Nordigen-Node-v2',
'Content-Length': '196',
'Accept-Encoding': 'gzip, compress, deflate, br'
},
method: 'post',
url: URL {
href: 'https://ob.gocardless.com/api/v2/token/new/',
origin: 'https://ob.gocardless.com',
protocol: 'https:',
username: '',
password: '',
host: 'ob.gocardless.com',
hostname: 'ob.gocardless.com',
port: '',
pathname: '/api/v2/token/new/',
search: '',
searchParams: URLSearchParams {},
hash: ''
},
data: '{"secret_key":"[REDACTED]","secret_id":"[REDACTED]"}'
},
request: ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
finish: [Function: requestOnFinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: '196',
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'ob.gocardless.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 10,
connecting: false,
_hadError: false,
_parent: null,
_host: 'ob.gocardless.com',
_closeAfterHandlingError: false,
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(alpncallback)]: null,
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: 8543,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kSetNoDelay)]: false,
[Symbol(kSetKeepAlive)]: true,
[Symbol(kSetKeepAliveInitialDelay)]: 60,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'POST /api/v2/token/new/ HTTP/1.1\r\n' +
'Accept: application/json\r\n' +
'Content-Type: application/json\r\n' +
'User-Agent: Nordigen-Node-v2\r\n' +
'Content-Length: 196\r\n' +
'Accept-Encoding: gzip, compress, deflate, br\r\n' +
'Host: ob.gocardless.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype],
freeSockets: [Object: null prototype] {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
joinDuplicateHeaders: undefined,
path: '/api/v2/token/new/',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
rawHeaders: [Array],
rawTrailers: [],
joinDuplicateHeaders: undefined,
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 403,
statusMessage: 'Forbidden',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://ob.gocardless.com/api/v2/token/new/',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: [Object],
[Symbol(kHeadersCount)]: 10,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'ob.gocardless.com',
protocol: 'https:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 196,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://ob.gocardless.com/api/v2/token/new/',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
'user-agent': [Array],
'content-length': [Array],
'accept-encoding': [Array],
host: [Array]
},
[Symbol(errored)]: null,
[Symbol(kHighWaterMark)]: 16384,
[Symbol(kRejectNonStandardBodyWrites)]: false,
[Symbol(kUniqueHeaders)]: null
},
response: {
status: 403,
statusText: 'Forbidden',
headers: T [AxiosHeaders] {
'content-length': '134',
'content-type': 'text/html; charset=UTF-8',
date: 'Sun, 03 Mar 2024 17:38:47 GMT',
'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
connection: 'close'
},
config: {
transitional: [Object],
adapter: [Array],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: [Object],
validateStatus: [Function: validateStatus],
headers: [T [AxiosHeaders]],
method: 'post',
url: [URL],
data: '{"secret_key":"[REDACTED]","secret_id":"[REDACTED]"}'
},
request: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: '196',
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: [TLSSocket],
_header: 'POST /api/v2/token/new/ HTTP/1.1\r\n' +
'Accept: application/json\r\n' +
'Content-Type: application/json\r\n' +
'User-Agent: Nordigen-Node-v2\r\n' +
'Content-Length: 196\r\n' +
'Accept-Encoding: gzip, compress, deflate, br\r\n' +
'Host: ob.gocardless.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
joinDuplicateHeaders: undefined,
path: '/api/v2/token/new/',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'ob.gocardless.com',
protocol: 'https:',
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kHighWaterMark)]: 16384,
[Symbol(kRejectNonStandardBodyWrites)]: false,
[Symbol(kUniqueHeaders)]: null
},
data: '403403 Forbidden'
}
}
```

### Where are you hosting Actual?

Docker

### What browsers are you seeing the problem on?

Firefox, Chrome

### Operating System

Linux

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.