Open Side Menu Go to the Top

10-09-2018 , 04:51 AM
Quote:
Originally Posted by microbet
Is this real work for them? If so, that's bs imo. They should pay you for a short term contract.
I don't know. Definitely seems possible at this point. I would expect a mini project to demonstrate capability not solve problems that seem very specific to them.

Quote:
Originally Posted by Larry Legend
Sounds like those things are there for you to fix.
I don't believe so. What I am being asked to do is extend the mini-project to add functionality that doesn't exist. The problem is the base project that I'm supposed to be extending seems to be broken. Here's an example pulled from the project readme of a task they are expecting me to do:

Quote:
## Issue 9: Filter leaderboard
Teachers want to filter the list based on particular criteria:

* Student name
* Teacher name
* Score range
* Grade level (not currently displayed)
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
10-09-2018 , 09:10 AM
Quote:
Originally Posted by microbet
Cool. I was playing around with it. Here it is in python. The arrays don't need that extra value in there, but that's left over my the last one I did.

Code:
#/usr/bin/python

grid = []
row = [[1,0], [1,0], [1,0], [0,0], [1,0], [1,0]]
grid.append(row)
row = [[1,0], [0,0], [1,0], [0,0], [0,0], [1,0]]
grid.append(row)
row = [[1,0], [0,0], [1,0], [0,0], [0,0], [1,0]]
grid.append(row)
row = [[1,0], [1,0], [1,0], [0,0], [1,0], [1,0]]
grid.append(row)
row = [[0,0], [0,0], [0,0], [0,0], [0,0], [0,0]]
grid.append(row)
row = [[0,0], [0,0], [0,0], [0,0], [0,0], [0,0]]
grid.append(row)

def dfs(grid, row, col):
    if row < 0 or row >= len(grid) or col < 0 or col >= len(grid[0]): 
        return 
    if (grid[row][col][0] != 1):
        return
    grid[row][col] = [0,0]
    dfs(grid, row + 1, col)
    dfs(grid, row - 1, col)
    dfs(grid, row, col + 1)
    dfs(grid, row, col - 1)

count = 0

for i in range(len(grid)): 
    for j in range(len(grid[i])):
        print(grid[i][j][0])
        if grid[i][j][0] == 1: 
                count = count + 1
                dfs(grid, i, j)

print("number of islands: ", count)
Cool it looks good, python is a nice language to read.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 01:36 PM
So, I have a react project - and node/express on my desktop. That involved all the npm install and create-react stuff that created megabytes of node modules and such. I have created a repo on github and pushed the src and public directories up there. It seems like you don't push all the node megabytes, right?

But I want to pull/clone this on my laptop. If I create the project and all the node junk first and then try cloning - the directory exists. If I clone it and then try npm install create etc...the directory exists.

What do I do - to do it right?

put it all on github?

clone github on the laptop, temporarily rename the directory, do the npm install stuff, then replace the src and public directories?

other?

Am I just sweating because I'm old and come from a world of kilobytes and megabytes and now it's a world of gigabytes and terrabytes?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 02:24 PM
Correct - don't check in node_modules. You should have a .gitignore file that tells git to ignore node_modules and other things. Don't use IDE-based git ignore stuff that doesn't create a .gitignore file in the root.

Easiest way to turn existing code into a new repo is to just create the repo on github, then clone to empty folder, then copy your code over. There are other ways but I always have to google and fight with it for a bit. Run npm install for new repos.

Also check out github CI/CD to have it run tests, build and push your app to wherever you're hosting it. Travis CI is really cool. (Easiest way is to find an app like yours on github and just copy what they do.)

Do pull requests for major changes so you have a nice clean record of what was added (also easy way to watch progress if you integrate CI/CD).
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 02:32 PM
So on my laptop, don't clone. Do the npm install and then pull? That will replace the files? Do I git init or something?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 02:38 PM
You checked into git from your desktop right? Just clone the repo to an empty folder on your laptop and run npm install.

Also the command line geeks on here will protest - but you might look into SourceTree. The gui interface will help guide you through this stuff. And there's even a console view where you can see every git command it's making under the covers - a great way to learn.

In source tree you just want New:Clone from URL from the little popup view that shows all your repos (Ctrl/Cmd-0).
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 02:40 PM
Quote:
Originally Posted by microbet
So on my laptop, don't clone. Do the npm install and then pull? That will replace the files? Do I git init or something?
In a nutshell, the things required for your app are listed in package.json. You publish package.json along with your actual code somehow (usually through a git repo) and once you've cloned the repo on another machine when you npm install it will use package.json to find dependencies.

So on your source machine you could follow the github instructions for creating a repo from existing sources, committing your existing code including the package.json and a .gitignore listing node_modules. On your laptop you would clone the git repo, at which point you have a copy of all your code, and the package.json. At that point doing an npm install will fetch all your dependencies. Note you have to install npm on your laptop first as well.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 03:33 PM
Super-duper cool!!! Thanks. I now have dev environment on laptop and desktop. I had been trying to run create-react-project whatever and it didn't like there already being a directory. npm install worked, but I had to check in and move the package.json and then there were a bunch of files that I had forgotten to check in blah blah, but it works now.

I've been getting some pain from sitting at the desktop so much in the same position and need to mix it up with the laptop. Also, I want to get used to the modern way of developing with git repositories. Back in the day I did use CVS a little, but not much.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 03:41 PM
The key concept with git is you have two copies of your repo - local and remote (github).

Clone = make new local copy of repo
Pull = get latest code from remote repo (for working branch)
Stage = pre-commit to your local repo (I'm sure there's a good reason for this separation, but for me stage, commit, push is always all done together)
Commit = put your new local code into your local repo (for working branch)
Push = push your code from local repo to remote repo (for working branch)
Branch = make a new branch (you might not have to worry much about branches as a 1-man show, but you still might want to do some CI-CD triggers off master or something)
Checkout = pull and switch to a new branch from the remote repo
Stash = put some code changes off to the side to possibly save for later
Fetch = get all local branches current with their remote counterparts (try this if you get weird local errors about things out of sync)

Pull Request (confusingly named) = merge from one branch to another on the remote repo (must be initiated on github). Very good for documenting stuff like version changes and triggering things - like automated tests and builds. Some git platforms call this a Merge Request instead.

Always merge, don't rebase. It will just get you in trouble. Rebase is mostly just to clean up commit history.

One weird thing that might trip you up is git doesn't know what folders are outside of the context of a file. So if you want to add an empty folder you have to put a file in it.

Also renaming files from lower/upper case (same letters) can get weird. Use an intermediate step. IE - MyFile -> myfile1 -> myfile. In general don't use upper case in your filenames.

List anything you don't want to check in in your .gitgnore file. This includes node_modules or stuff like logs - or on mac the annoying .DS_Store file.

Do check-in package.lock.json - which is generated the first time you run npm install. This makes sure everyone is on the same version of dependencies.

If you use SourceTree set Preferences:Git:Push Branches to "current". No idea why that isn't the default. You can also tell it to always Stage, Commit and Push in basically the same step.

Last edited by suzzer99; 10-09-2018 at 03:54 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 03:43 PM
Bookmarked
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 04:49 PM
Cragoo,

You may be completely correct. But I know in our take home coding assignment there are intentional bugs to see if the candidate notices/fixes them, and I know other people who do the same.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 04:58 PM
any updates on dbag?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 05:10 PM
i always stage when doing commits, i think it's less error prone than just git commit -a or something.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 06:01 PM
Quote:
Originally Posted by iversonian
any updates on dbag?
Nothing visible, lots of us who were watching had a good laugh about the whole thing (most coworkers I've talked to about him also think he's a dbag). I imagine he probably got a stern warning from the VP or something.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 06:29 PM
Is there any way to do error handling with async/await w/o wrapping your await calls in try/catch blocks?

Do most people just have the promise always resolve instead of reject - and then have an optional error object in the resolve payload? IE - like the common callback(err, data) pattern?

It seems like using reject() with async/await for normal operation flow would get messy real fast. For instance, here's the example code for lambda function that goes to a dynamoDB with the old callback pattern:

Code:
module.exports.firstRun = (event, context, callback) => {
  docClient.scan(params, (err, data) => {
    if (err) {
      console.error(err);
      callback({err});
    }
    else {
      console.log(data);
      callback({data});
    }
  });
};
and here's it with the new async await:

Code:
module.exports.firstRun = async (event, context) => {

  let dbData = new Promise((resolve, reject) => {
    docClient.scan(params, (err, data) => {

      if (err) {
        console.error(err);
        reject(err);
      }
      else {
        console.log(data);
        resolve(data);
      }
    });
  });

  try { return { dbData: await dbData } }
  catch (e) { return({err:e}) }
};

Hmmm yeah looks like try/catch is it: https://stackoverflow.com/questions/...c-await-syntax I guess I like chaining the function with .catch() marginally better.

I still think the old-school async.js has the cleanest error-handling patterns of anything. What's nice is it's the same pattern for sequential, parallel or waterfall. So it's a lot easier to mix and match functions in different async flows.

Last edited by suzzer99; 10-09-2018 at 06:56 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 07:13 PM
However if we stick to a convention of returning an object with an error property, and a data property - then the code doesn't look bad.

Code:
module.exports.firstRun = async (event, context) => {

  return await new Promise((resolve, reject) => {
    docClient.scan(params, (error, data) => {
      resolve({error, data});
    });
  });
};
reject() just really seems to gunk things up for this type of use.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 07:57 PM
A)
imo,
Code:
return await...
is an anti pattern.

The only time
Code:
return await
is needed is when you are trying to explicitly catch a rejection, but if you are just returning the result anyways, the try catch should be a layer higher anyways.

B)
What you are doing is promisifying a callback (which actually has a native function to do for you http://2ality.com/2017/05/util-promisify.html), so you absolutely need to reject and again, deal with that rejection higher up

Last edited by PJo336; 10-09-2018 at 07:58 PM. Reason: slack formatting removed ;)
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 08:14 PM
The top level function:

Code:
module.exports.firstRun = async (event, context) => {
is called by the lambda framework. It expects a return. The db.scan function, which executes a callback, is also part of the aws-sdk. So I'm kind of sandwiched between those two things.

https://aws.amazon.com/blogs/compute...in-aws-lambda/

This is their basic example:

Code:
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();

exports.handler = async (event) => {
    return await lambda.getAccountSettings().promise() ;
};
Although looks like I could return a promise instead:

Code:
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();

exports.handler = (event) => {
    return new Promise((resolve, reject) => {
        lambda.getAccountSettings(event)
        .then((data) => {
            resolve data;
        })
        .catch(reject);
     });
};
Hmmmm

Quote:
Another great advantage of async/await is better error handling. You can use a try/catch block inside the scope of an async function. Even though the function awaits an asynchronous operation, any errors end up in the catch block.

You can improve your previous Node.js 8.10 function with this trusted try/catch error handling pattern:
Code:
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();
let data;

exports.handler = async (event) => {
    try {
        data = await lambda.getAccountSettings().promise();
    }
    catch (err) {
        console.log(err);
        return err;
    }
    return data;
};
Really? try/catch is a beloved error handling pattern? I feel like I can count on one hand the # of times I've needed try/catch in my JS code the last 5 years or so. I know I didn't miss it.

Last edited by suzzer99; 10-09-2018 at 08:23 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 08:17 PM
ah gross. Does the lambda handler handle promises though? I would assume if you can return a promise to the handler, it should have some sort of rejection handling, or else that is really gross.

Your last example leaves no reason to make it an async function in the first place

Code:
module.exports.firstRun = (event, context, callback) => {
    docClient.scan(params, (error, data) => {
      if(error) {
        callback(error)
      } else {
        return or whatever you need to do here with data
      }
    });
};

Last edited by PJo336; 10-09-2018 at 08:20 PM. Reason: wow typing code in these dialogue boxes is infuriating :P
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 08:22 PM
Yeah see my edits. The code snipped you posted is the older lambda invoke handler - using callbacks - which is still supported.

Serverless framework automatically generated a lambda with the new async pattern. So I thought I'd try it out.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 08:27 PM
A)
Totally agree on try/catch. I think it is a dog**** pattern and even easier to mess up than .catch and .then

B)
That code example is atrocious. Await is not needed on a return statement unless you are explicitly trying to catch an error
ie
Code:
async foo() {
  try {
    return somePromise();
  } catch(error) {
    // never happens
  }
}
Code:
async foo() {
  try {
    return await somePromise();
  } catch(error) {
    // does happen
  }
}
But again, if their handlers support promises, there is no reason to await without your own catch wrapper. That example is terribad, and I feel like they don't really understand promises in general since they wrap all their **** in their own Promise types and make you use .promise() lol
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 08:28 PM
Does returning an error work also? All my lambdas I took a look at use the callback arg in case of error, like callback(err)


ETA the whole point is this example makes no sense
Code:
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();

exports.handler = async (event) => {
    return await lambda.getAccountSettings().promise() ;
};
it should work the same as
Code:
exports.handler = (event) => {
    return lambda.getAccountSettings().promise() ;
};
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 08:46 PM
Yeah this works, pretty clean I guess:

Code:
module.exports.firstRun = (event, context) => {
  return new Promise((resolve, reject) => {
    docClient.scan(params, (err, data) => {
      if (err) reject(err);
      else resolve(data);
    });
  });
};
Basically the only difference is you get the big red - execution failed if you trigger an error. In both cases you get a payload.

So if you're calling this from another lambda or API gateway - I wonder how that would work. The call must be a promise.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 08:50 PM
Im still not really clear why you need to wrap it in a promise there though
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-09-2018 , 08:56 PM
Because the docClient.scan function is asynchronous and executes a callback when the data comes back from the DB.

So one way or another firstRun needs to an asynchronous function - whether it executes a supplied callback (old lambda handler method signature), is an async method that awaits the outcome of a promise, or returns a promise. Otherwise the function returns before the db.scan callback is ever executed.

This has been a good lesson in async/await - which I've never really worked with. I definitely get it now. Still not sure about best practices, but I get what's happening.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **

      
m