Exception handling and releasing of OracleDB connection

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












Before I start implementing several REST API service endpoints, I'd like to make sure that I'm not doing it totally wrong.



/**
* GET /api/test
* Test API example.
*/
export let getTest = (req: Request, res: Response, next: NextFunction) =>
// const token = req.user.tokens.find((token: any) => token.kind === "facebook");
const db = new Database();

db.getConnection()
.then(con =>
con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
.then(result =>
con.release();
res.json(data: result.rows);
)
.catch(ex =>
con.release();
res.status(500).json(message: ex.message);
);
)
.catch(ex =>
res.status(500).json(message: ex.message);
);

;


  • Is the connection always released properly, or have I forgotten something?


  • What seems a bit messy is that I need to release the connection two times, and that I have two catch'es, since I cannot release the connection in the second catch.


For completeness: Database is simply a wrapper that contains the connection string configuration and returns a reference to a new connection:



import * as oracledb from 'oracledb';
import IConnectionPool from 'oracledb';

const config =
user: 'user',
password: 'pw',
connectString: 'databaseNameFromTNSNames',
poolMax: 16
;

export default class Database
private pool: IConnectionPool;
constructor()


public createPool(): void
oracledb.createPool(config).then(conpool =>
this.pool = conpool;
console.log('Connection Pool created!');
,
err =>
console.log('Error creating pool!');
);


public getConnection()
return oracledb.getConnection();








share|improve this question





















  • I think the code looks fairly okay. You can improve a bit using async-await if possible.
    – Garbage
    Jan 18 at 10:19

















up vote
0
down vote

favorite












Before I start implementing several REST API service endpoints, I'd like to make sure that I'm not doing it totally wrong.



/**
* GET /api/test
* Test API example.
*/
export let getTest = (req: Request, res: Response, next: NextFunction) =>
// const token = req.user.tokens.find((token: any) => token.kind === "facebook");
const db = new Database();

db.getConnection()
.then(con =>
con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
.then(result =>
con.release();
res.json(data: result.rows);
)
.catch(ex =>
con.release();
res.status(500).json(message: ex.message);
);
)
.catch(ex =>
res.status(500).json(message: ex.message);
);

;


  • Is the connection always released properly, or have I forgotten something?


  • What seems a bit messy is that I need to release the connection two times, and that I have two catch'es, since I cannot release the connection in the second catch.


For completeness: Database is simply a wrapper that contains the connection string configuration and returns a reference to a new connection:



import * as oracledb from 'oracledb';
import IConnectionPool from 'oracledb';

const config =
user: 'user',
password: 'pw',
connectString: 'databaseNameFromTNSNames',
poolMax: 16
;

export default class Database
private pool: IConnectionPool;
constructor()


public createPool(): void
oracledb.createPool(config).then(conpool =>
this.pool = conpool;
console.log('Connection Pool created!');
,
err =>
console.log('Error creating pool!');
);


public getConnection()
return oracledb.getConnection();








share|improve this question





















  • I think the code looks fairly okay. You can improve a bit using async-await if possible.
    – Garbage
    Jan 18 at 10:19













up vote
0
down vote

favorite









up vote
0
down vote

favorite











Before I start implementing several REST API service endpoints, I'd like to make sure that I'm not doing it totally wrong.



/**
* GET /api/test
* Test API example.
*/
export let getTest = (req: Request, res: Response, next: NextFunction) =>
// const token = req.user.tokens.find((token: any) => token.kind === "facebook");
const db = new Database();

db.getConnection()
.then(con =>
con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
.then(result =>
con.release();
res.json(data: result.rows);
)
.catch(ex =>
con.release();
res.status(500).json(message: ex.message);
);
)
.catch(ex =>
res.status(500).json(message: ex.message);
);

;


  • Is the connection always released properly, or have I forgotten something?


  • What seems a bit messy is that I need to release the connection two times, and that I have two catch'es, since I cannot release the connection in the second catch.


For completeness: Database is simply a wrapper that contains the connection string configuration and returns a reference to a new connection:



import * as oracledb from 'oracledb';
import IConnectionPool from 'oracledb';

const config =
user: 'user',
password: 'pw',
connectString: 'databaseNameFromTNSNames',
poolMax: 16
;

export default class Database
private pool: IConnectionPool;
constructor()


public createPool(): void
oracledb.createPool(config).then(conpool =>
this.pool = conpool;
console.log('Connection Pool created!');
,
err =>
console.log('Error creating pool!');
);


public getConnection()
return oracledb.getConnection();








share|improve this question













Before I start implementing several REST API service endpoints, I'd like to make sure that I'm not doing it totally wrong.



/**
* GET /api/test
* Test API example.
*/
export let getTest = (req: Request, res: Response, next: NextFunction) =>
// const token = req.user.tokens.find((token: any) => token.kind === "facebook");
const db = new Database();

db.getConnection()
.then(con =>
con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
.then(result =>
con.release();
res.json(data: result.rows);
)
.catch(ex =>
con.release();
res.status(500).json(message: ex.message);
);
)
.catch(ex =>
res.status(500).json(message: ex.message);
);

;


  • Is the connection always released properly, or have I forgotten something?


  • What seems a bit messy is that I need to release the connection two times, and that I have two catch'es, since I cannot release the connection in the second catch.


For completeness: Database is simply a wrapper that contains the connection string configuration and returns a reference to a new connection:



import * as oracledb from 'oracledb';
import IConnectionPool from 'oracledb';

const config =
user: 'user',
password: 'pw',
connectString: 'databaseNameFromTNSNames',
poolMax: 16
;

export default class Database
private pool: IConnectionPool;
constructor()


public createPool(): void
oracledb.createPool(config).then(conpool =>
this.pool = conpool;
console.log('Connection Pool created!');
,
err =>
console.log('Error creating pool!');
);


public getConnection()
return oracledb.getConnection();










share|improve this question












share|improve this question




share|improve this question








edited Jan 21 at 5:03









Jamal♦

30.1k11114225




30.1k11114225









asked Jan 9 at 15:00









user66875

707




707











  • I think the code looks fairly okay. You can improve a bit using async-await if possible.
    – Garbage
    Jan 18 at 10:19

















  • I think the code looks fairly okay. You can improve a bit using async-await if possible.
    – Garbage
    Jan 18 at 10:19
















I think the code looks fairly okay. You can improve a bit using async-await if possible.
– Garbage
Jan 18 at 10:19





I think the code looks fairly okay. You can improve a bit using async-await if possible.
– Garbage
Jan 18 at 10:19











1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted
+50










There really isn't too much to say about your posted code.



Answering your specific question:



Yes, the connection will always be released as either your then or your catch method will always run. However, if res.json(data: result.rows); (or more complex code once you have developed further) throws, your code will try to release the connection twice. This will likely result in an uncaught promise rejection. You can solve this problem a couple different ways.




  1. Use the second callback parameter of the .then method.



    con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
    .then(result =>
    con.release();
    res.json(data: result.rows);
    , ex =>
    con.release();
    res.status(500).json(message: ex.message);
    )



  2. Use async / await and take advantage of the finally in try..catch..finally chain. This solution also has the benefit of avoiding the duplicate code sending error messages. I like this solution the best, but it would probably be even better to have an execute method on your Database class that handles releasing the connection for you.



    export let getTest = async (req: Request, res: Response, next: NextFunction) => 
    const db = new Database();

    try
    const con = await db.getConnection();
    try
    const result = await con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 );
    res.json( data: result.rows );
    finally
    con.release();

    catch (ex)
    res.status(500).json( message: ex.message );

    ;



  3. For the future: Promise.prototype.finally is coming, currently a stage 3 proposal. Proposal. I wouldn't use this just yet.



    db.getConnection()
    .then(con =>
    return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
    .then(result =>
    res.json( data: result.rows );
    )
    .finally(() =>
    con.release();
    )
    )
    .catch(ex =>
    res.status(500).json( message: ex.message );
    );


The trick to using promises effectively is to return them whenever possible. The original function can be somewhat simplified by re-throwing the error and returning the connection promise. This doesn't help a ton but it does remove the duplicate res.status(500) line, making it easier to change in the future if necessary.



db.getConnection()
.then(con =>
return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
.then(result =>
con.release();
res.json( data: result.rows );
, ex =>
con.release();
throw ex;
)
)
.catch(ex =>
res.status(500).json( message: ex.message );
);





share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184660%2fexception-handling-and-releasing-of-oracledb-connection%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted
    +50










    There really isn't too much to say about your posted code.



    Answering your specific question:



    Yes, the connection will always be released as either your then or your catch method will always run. However, if res.json(data: result.rows); (or more complex code once you have developed further) throws, your code will try to release the connection twice. This will likely result in an uncaught promise rejection. You can solve this problem a couple different ways.




    1. Use the second callback parameter of the .then method.



      con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
      .then(result =>
      con.release();
      res.json(data: result.rows);
      , ex =>
      con.release();
      res.status(500).json(message: ex.message);
      )



    2. Use async / await and take advantage of the finally in try..catch..finally chain. This solution also has the benefit of avoiding the duplicate code sending error messages. I like this solution the best, but it would probably be even better to have an execute method on your Database class that handles releasing the connection for you.



      export let getTest = async (req: Request, res: Response, next: NextFunction) => 
      const db = new Database();

      try
      const con = await db.getConnection();
      try
      const result = await con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 );
      res.json( data: result.rows );
      finally
      con.release();

      catch (ex)
      res.status(500).json( message: ex.message );

      ;



    3. For the future: Promise.prototype.finally is coming, currently a stage 3 proposal. Proposal. I wouldn't use this just yet.



      db.getConnection()
      .then(con =>
      return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
      .then(result =>
      res.json( data: result.rows );
      )
      .finally(() =>
      con.release();
      )
      )
      .catch(ex =>
      res.status(500).json( message: ex.message );
      );


    The trick to using promises effectively is to return them whenever possible. The original function can be somewhat simplified by re-throwing the error and returning the connection promise. This doesn't help a ton but it does remove the duplicate res.status(500) line, making it easier to change in the future if necessary.



    db.getConnection()
    .then(con =>
    return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
    .then(result =>
    con.release();
    res.json( data: result.rows );
    , ex =>
    con.release();
    throw ex;
    )
    )
    .catch(ex =>
    res.status(500).json( message: ex.message );
    );





    share|improve this answer

























      up vote
      1
      down vote



      accepted
      +50










      There really isn't too much to say about your posted code.



      Answering your specific question:



      Yes, the connection will always be released as either your then or your catch method will always run. However, if res.json(data: result.rows); (or more complex code once you have developed further) throws, your code will try to release the connection twice. This will likely result in an uncaught promise rejection. You can solve this problem a couple different ways.




      1. Use the second callback parameter of the .then method.



        con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
        .then(result =>
        con.release();
        res.json(data: result.rows);
        , ex =>
        con.release();
        res.status(500).json(message: ex.message);
        )



      2. Use async / await and take advantage of the finally in try..catch..finally chain. This solution also has the benefit of avoiding the duplicate code sending error messages. I like this solution the best, but it would probably be even better to have an execute method on your Database class that handles releasing the connection for you.



        export let getTest = async (req: Request, res: Response, next: NextFunction) => 
        const db = new Database();

        try
        const con = await db.getConnection();
        try
        const result = await con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 );
        res.json( data: result.rows );
        finally
        con.release();

        catch (ex)
        res.status(500).json( message: ex.message );

        ;



      3. For the future: Promise.prototype.finally is coming, currently a stage 3 proposal. Proposal. I wouldn't use this just yet.



        db.getConnection()
        .then(con =>
        return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
        .then(result =>
        res.json( data: result.rows );
        )
        .finally(() =>
        con.release();
        )
        )
        .catch(ex =>
        res.status(500).json( message: ex.message );
        );


      The trick to using promises effectively is to return them whenever possible. The original function can be somewhat simplified by re-throwing the error and returning the connection promise. This doesn't help a ton but it does remove the duplicate res.status(500) line, making it easier to change in the future if necessary.



      db.getConnection()
      .then(con =>
      return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
      .then(result =>
      con.release();
      res.json( data: result.rows );
      , ex =>
      con.release();
      throw ex;
      )
      )
      .catch(ex =>
      res.status(500).json( message: ex.message );
      );





      share|improve this answer























        up vote
        1
        down vote



        accepted
        +50







        up vote
        1
        down vote



        accepted
        +50




        +50




        There really isn't too much to say about your posted code.



        Answering your specific question:



        Yes, the connection will always be released as either your then or your catch method will always run. However, if res.json(data: result.rows); (or more complex code once you have developed further) throws, your code will try to release the connection twice. This will likely result in an uncaught promise rejection. You can solve this problem a couple different ways.




        1. Use the second callback parameter of the .then method.



          con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
          .then(result =>
          con.release();
          res.json(data: result.rows);
          , ex =>
          con.release();
          res.status(500).json(message: ex.message);
          )



        2. Use async / await and take advantage of the finally in try..catch..finally chain. This solution also has the benefit of avoiding the duplicate code sending error messages. I like this solution the best, but it would probably be even better to have an execute method on your Database class that handles releasing the connection for you.



          export let getTest = async (req: Request, res: Response, next: NextFunction) => 
          const db = new Database();

          try
          const con = await db.getConnection();
          try
          const result = await con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 );
          res.json( data: result.rows );
          finally
          con.release();

          catch (ex)
          res.status(500).json( message: ex.message );

          ;



        3. For the future: Promise.prototype.finally is coming, currently a stage 3 proposal. Proposal. I wouldn't use this just yet.



          db.getConnection()
          .then(con =>
          return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
          .then(result =>
          res.json( data: result.rows );
          )
          .finally(() =>
          con.release();
          )
          )
          .catch(ex =>
          res.status(500).json( message: ex.message );
          );


        The trick to using promises effectively is to return them whenever possible. The original function can be somewhat simplified by re-throwing the error and returning the connection promise. This doesn't help a ton but it does remove the duplicate res.status(500) line, making it easier to change in the future if necessary.



        db.getConnection()
        .then(con =>
        return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
        .then(result =>
        con.release();
        res.json( data: result.rows );
        , ex =>
        con.release();
        throw ex;
        )
        )
        .catch(ex =>
        res.status(500).json( message: ex.message );
        );





        share|improve this answer













        There really isn't too much to say about your posted code.



        Answering your specific question:



        Yes, the connection will always be released as either your then or your catch method will always run. However, if res.json(data: result.rows); (or more complex code once you have developed further) throws, your code will try to release the connection twice. This will likely result in an uncaught promise rejection. You can solve this problem a couple different ways.




        1. Use the second callback parameter of the .then method.



          con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
          .then(result =>
          con.release();
          res.json(data: result.rows);
          , ex =>
          con.release();
          res.status(500).json(message: ex.message);
          )



        2. Use async / await and take advantage of the finally in try..catch..finally chain. This solution also has the benefit of avoiding the duplicate code sending error messages. I like this solution the best, but it would probably be even better to have an execute method on your Database class that handles releasing the connection for you.



          export let getTest = async (req: Request, res: Response, next: NextFunction) => 
          const db = new Database();

          try
          const con = await db.getConnection();
          try
          const result = await con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 );
          res.json( data: result.rows );
          finally
          con.release();

          catch (ex)
          res.status(500).json( message: ex.message );

          ;



        3. For the future: Promise.prototype.finally is coming, currently a stage 3 proposal. Proposal. I wouldn't use this just yet.



          db.getConnection()
          .then(con =>
          return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
          .then(result =>
          res.json( data: result.rows );
          )
          .finally(() =>
          con.release();
          )
          )
          .catch(ex =>
          res.status(500).json( message: ex.message );
          );


        The trick to using promises effectively is to return them whenever possible. The original function can be somewhat simplified by re-throwing the error and returning the connection promise. This doesn't help a ton but it does remove the duplicate res.status(500) line, making it easier to change in the future if necessary.



        db.getConnection()
        .then(con =>
        return con.execute('SELECT * FROM BTO_MDS.AlARMS', , maxRows: 22000 )
        .then(result =>
        con.release();
        res.json( data: result.rows );
        , ex =>
        con.release();
        throw ex;
        )
        )
        .catch(ex =>
        res.status(500).json( message: ex.message );
        );






        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jan 21 at 4:43









        Gerrit0

        2,6701518




        2,6701518






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184660%2fexception-handling-and-releasing-of-oracledb-connection%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Python Lists

            Aion

            JavaScript Array Iteration Methods