MunifTanjim / node-bitbucket

Bitbucket API client for Browser and Node.js
https://bitbucketjs.netlify.app
MIT License
106 stars 28 forks source link

Internal server error when trying to list files on branch.. #70

Closed rlyle closed 4 years ago

rlyle commented 4 years ago

We have the following function to list files in a repo under a given branch:

    listFiles(workspace, repo_slug, branch, dir, page = undefined ) {
        const self = this;
        return new Promise((resolve, reject) => {
            let params = { workspace, repo_slug, node: branch, path: dir, pagelen: PAGE_SIZE, page };
            log.info("listFiles:", params );
            bitbucket.source.read(params).then(({data}) => {
                //log.info("listFiles response:", data );
                let response = { files: data.values };
                let nextPage = getUrlValue( data.next, 'page' );
                if ( nextPage ) {
                    // recursively call ourselves to get all pages..
                    self.listFiles( workspace, repo_slug,branch, dir, nextPage ).then((result) => {
                        response.files = result.files.concat( response.files );     // concat the files
                        resolve( response );
                    }).catch((err) => {
                        reject(err);
                    })
                }
                else {
                    log.debug("listFiles result:", data );
                    resolve( response );
                }
            }).catch((err) => {
                if ( err.message.indexOf('No such file or directory') >= 0 )
                    return resolve( { files: [] } );
                log.error("listFiles error:", err );
                reject(err);
            })
        });
    }

In the previous API, they had a listFiles function we could call, so it appears we need to use source.read() now, however when we call that, we are getting back an "internal server error" from the back-end.

service-common-lib:1.1.24 - :bitbucket.js:61  listFiles: {"workspace":"apricityhealth","repo_slug":"apricity-data","node":"test-branch","path":"test/","pagelen":100} (2ms)
 service-common-lib:1.1.24 - :bitbucket.js:82  listFiles error: Error: Internal Server Error
    at F:\Work\Apricity\services\rosetta\src\lib\common\node_modules\bitbucket\src\request\fetch-wrapper.ts:48:17
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)

We are using the latest 2.4.0 version...

rlyle commented 4 years ago

Sorry, in the previous API we could call bitbucket.source.get() to retrieve a list of files in a repo on a given branch..

MunifTanjim commented 4 years ago

Seem's like the error is coming from Bitbucket's API Server.

Can you try running your script with DEBUG=bitbucket environment variable set and paste the output here? That would give us more information about where it went wrong.

rlyle commented 4 years ago

I did do that already, but not seeing anything in the logs..

I even tried putting this line right before the call in node.js: process.env['DEBUG'] = 'bitbucket';

still no additional logs are getting generated to the output?

rlyle commented 4 years ago

I got the internal server error to go away by providing the format: 'meta' in the parameters to the function, however I'm no longer seeing a list of files in the directory coming back anymore:

{
    "path": "test",
    "type": "commit_directory",
    "links": {
        "self": {
            "href": "https://api.bitbucket.org/2.0/repositories/apricityhealth/apricity-data/src/74c8e268fd9bba6cf38f181d62a6fbb3a8850f11/test/"
        },
        "meta": {
            "href": "https://api.bitbucket.org/2.0/repositories/apricityhealth/apricity-data/src/74c8e268fd9bba6cf38f181d62a6fbb3a8850f11/test/?format=meta"
        }
    },
    "commit": {
        "type": "commit",
        "hash": "74c8e268fd9bba6cf38f181d62a6fbb3a8850f11",
        "links": {
            "self": {
                "href": "https://api.bitbucket.org/2.0/repositories/apricityhealth/apricity-data/commit/74c8e268fd9bba6cf38f181d62a6fbb3a8850f11"
            },
            "html": {
                "href": "https://bitbucket.org/apricityhealth/apricity-data/commits/74c8e268fd9bba6cf38f181d62a6fbb3a8850f11"
            }
        }
    }
}

In the previous API, we got back an "values" array in the JSON, and got a list of all the files in the given directory. I know this probably doesn't have anything to do with your implementation now, since this seems to be a problem with the bitbucket API.

rlyle commented 4 years ago

what would be the correct function to call in your package for this end-point: https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/src/%7Bnode%7D/%7Bpath%7D

rlyle commented 4 years ago

ok, finally solved my problem by using Axios and making the call directly... I think the problem is that we didn't want the "format" query parameter on the end to get the files in the given directory, the format: meta was fixing the internal server error, but it was only returning meta information for the directory in the end.

    listFiles(workspace, repo_slug, branch, dir, page = undefined ) {
        const self = this;
        return new Promise((resolve, reject) => {

            let token = Buffer.from(`${Config.get('bitbucket.username')}:${Config.get('bitbucket.password')}`, 'utf8').toString('base64');
            let request = {
                url: Config.get('bitbucket.url') + `/repositories/${workspace}/${repo_slug}/src/${branch}/${dir}`,
                method: 'GET',
                headers: {
                    'Authorization': `Basic ${token}`
                }
            };

            log.info("listFiles:", request );
            Axios(request).then(({data}) => {
                log.info("read response:", data );
                let response = { files: data.values };
                let nextPage = getUrlValue( data.next, 'page' );
                if ( nextPage ) {
                    // recursively call ourselves to get all pages..
                    self.listFiles( workspace, repo_slug,branch, dir, nextPage ).then((result) => {
                        response.files = result.files.concat( response.files );     // concat the files
                        resolve( response );
                    }).catch((err) => {
                        reject(err);
                    })
                }
                else {
                    log.debug("listFiles result:", response );
                    resolve( response );
                }
            }).catch((err) => {
                if ( err.message.indexOf('No such file or directory') >= 0 )
                    return resolve( { files: [] } );
                log.error("listFiles error:", err );
                reject(err);
            })
        });
    }
MunifTanjim commented 4 years ago

Thanks so much for discovering this bug! I really appreciate it 😄 @rlyle

The bug was in the query params processing. This library was sending query params like ?pagelen=10&page=undefined. But the undefined value should've been omitted.

This should be fixed in v2.4.1 🎉