Ticket, Handling Errors

It seems that the error being fired from the Mongo client does not contain the asked “InvalidId” at any point.

Is this correct?

Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters

1 Like

The question asks for you to recognize this string when it occurs

HINT: Not all errors messages are going to begin with the same words

So there is basically a way to code something that recognizes a pattern in this string and then return null when that is the case just like the instructions tell you.

FURTHER HINT: Read the question.and it’s own hint provided on that page:

When the error e is caught, it has type Error. You might want to convert this to a string.

So the “string” might not actually “start with” the word you think it does. Also “convert” is a a real “Java Programmer” point of view. No need to do that with JavaScript, which is what we are using here.

https://www.google.com/search?q=javascript+Error

Is worthwhile looking at as well

5 Likes

Thanks @neillunn. It was a theoritcal question, i was expecting something similar to “InvalidId” inside the e.codeName, e.name, or e.errmsg of the (e) error object.
I passed the test matching the error that was being thrown.

2 Likes

I am struck here too. I have no idea what it should be.
Richard

1 Like

@richardxu98 Perhaps you should click on the link in my response then. That’s a very big hint ( as well as the phrasing I use ) as to what you are meant to be doing here.

Also please refrain from “me too” responses, since they don’t really add anything. Posts here should be helpful content or a request for clarification of an earlier point.

Hi. I get this reponse and I don’t understand how to interpret it.

.
Along with this, I tried
(e.errmsg).toContain(“Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters”). Please help me understand what’s the mistake that I’m doing?

1 Like

@Abhinav_01445 You appear to be modifying the “unit test”. As has been noted here many times throughout the discussion of issues on this course Do NOT edit unit tests EVER.

That’s not your job and it’s not the task.

You are being asked to “Modify the getMovieByID() method in the moviesDAO.js file so that the catch block does ‘something’ to inspect and handle the error response when you receive an Error message recognized as the response received when you provide a string that is something other than a valid ObjectId value”.

Read my earlier entry on this thread. Pay attention to the wording I use, the highlighted and bolded terms ( because those are important and mean something ) and of course visit the reference link to external documentation of the JavaScript Error object, which basically tells you where to look.


N.B Please don’t paste screenshots of “text” either here on on any other such forum. It’s “text” after all, and copied “text” is much easier to read than squinting at ( or loading a lightbox for ) an image of a screen.

I passed the test, but I want to put forth a suggestion for @neillunn and instructors. From your Google search link, the first search result returns the MDN Error

From what I understand from the page, there is no InvalidId error type. The invalidid error is only our implementation of the code, not a native JavaScript error type. I believe this is what threw most people off track.

The ticket is quite simple, except that the wording is misleading. Instead of saying that students have to look for InvalidId error, why not just say look for the message that is returned by the error? This is just much more direct and easier to understand.

2 Likes

The answer to your question is actually directly in the first line of the page I linked you to ( and you included above yourself )

The Error constructor creates an error object.

An Object ( which is also what the question says ) is not a “message”. But when you look at the documentation for the Error Object then you should see some way to get the message, or otherwise known as “one of the object properties”.

So main reason the question is not actually worded the way you suggest is to avoid everyone complaining that when they attempt to compare a “string” to an Object it does not work. And there’s a reason for that.

Actually, that was what I did, ie. compare the e.message to a String and the test passed. From your reply, I did further read up. And the reason is this.

The `message` property combined with the `name` property is used by 
the `Error.prototype.toString()` method to create a string representation 
of the Error.

Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/message

Hence, e.message would have similar effect as e.toString(), as the toString() method is used underneath anyway by JavaScript.

1 Like

Not exactly. The problem here and in fact the main difference is that e.toString() will always start with "Error:" as part of the returned “string”. However e.message is just the actual “error message”, which is the part that comes after that aforementioned "Error: " string.

Like I have said earlier, concepts like String(e) or e.toString() are more a Java centric way of thinking as opposed to what is more canonically JavaScript in implementation. Being forcing something to “be a string” instead of simply “accessing the property that is a string”.


N.B In actual fact, one of the better things about strongly typed languages such as Java ( or at least where there is similar language support for this, but sadly not in JavaScript ) is “Typed Exceptions”.

For these, rather than “string checking” or any other form of effective “Duck Typing” you can actually catch for a specified “type of error”. As for example you could have an exception type which is only raised for the specific error of not matching the expected ObjectId format for the constructor.

But since this is JavaScript and we don’t have the luxury, this comes down to “string comparison”.

My initial reaction to this ticket was pretty much the same as Sotiris, I saw the instruction

Use the variable e to figure out if the InvalidId error is being thrown

Which my mind immediately translated into C# as

try {
  // data access code
} catch(InvalidIdException e) {
  // handle the exception
}

Of course, we’re using JavaScript here and things aren’t strongly typed, so instead I need to

try {
  // data access code
} catch(e) {
  // work out whether or not e is an InvalidId error
}

I worked it out and completed the ticket by testing the e.message property to determine what sort of Error I was handling, and I’ve now finished the course, but I think this topic is worth revisiting for two reasons:

  1. I think the use of the string InvalidId in the ticket instructions is misleading, because the compounding of two words into a single pascal-cased word implies that InvalidId is some kind of identifier within the code whch we can use when interrogating e to work out whether to handle it, when (as far as I can tell) that string doesn’t exist anywhere in e's properties, and
  2. I suspect this may point to a shortcoming in the way the driver throws errors

I don’t consider myself an expert in JavaScript, which is why I’d like to seek people’s thoughts here before I go raising a github issue against the MongoDB JS driver.

Testing the human-readable message associated with an error / execption feels to me like a really flaky way of working out what has happened. Yes, it worked for this ticket, but in a production application, what happens if we upgrade to the latest version of the driver and find that the Mongo dev team have decided that their error messages need to be more helpful, and that the new, helpful error messages, break our error handling because the messages no longer contain the same string we were looking for. Or maybe someone’s using a version of the driver which returns error messages in their own native language, which isn’t English?

In my mind, human-readable error messages are meant for reporting to humans to use in their decision making, they’re not really meant to be used by our code to make decisions.

What I think I was looking for when I originally saw the string InvalidId was something like this

class InvalidId extends Error {
    constructor(...args) {
        super(...args);
        this.name = "InvalidId";
    }
}

If the MongoDB JS driver threw this kind of error then we could test for it like this

try {
  // data access code
} catch(e) {
  if (e.name == "InvalidId") {
    // we're kinda expecting this sometimes
    return null;
  }

  // it's an error I don't know how to handle
  throw e;
}

And then all the messy business of trying to work out what has happened by parsing a human-readable error message goes away and instead we can make use of the fact that e.name is InvalidId to look up in the documentation exactly what category of error InvalidId is (even if its name isn’t meaningful in our native human language), and write some code to decide whether or how to handle it, with confidence that later updates to the driver to make it friendlier to humans won’t break our error handling code.

Like I said, I’m not an expert in JavaScript, and I’m certainly not an expert in MongoDB (that’s why I’m here, to learn about it), so I’m willing to accept that there could be any number of holes in the argument that I’ve set out above. If you can see them, please point them out :slightly_smiling_face:

7 Likes

HI @Simon_39939,

Thanks for sharing detailed feedback. We will work to revise this ticket to help students better understand.

Thanks again! :slight_smile:

Kanika

I personally gave up on finding the solution.After I saw the implementation, I can say that I would have NEVER thought about that only by reading the instructions…

3 Likes


because the test ID is not 12 bytes the error happens in line 305. Is this supposed to happen?

I agree these tasks are very poorly defined

2 Likes

In the end,if you read closely, the task is not as poorly defined, but then again I am saying this after getting help here. What helped me, is just type Error in my console, which returns a ‘function Error()’. In its constructor you can see it has a name: “Error”. That’s it!
Update:
Actually, the official solution is using the string from the response. You have to check how it starts with! So, for the JS beginners, lookup string methods!

Hi @kanikasingla

A quick note, since jest is configured to run all test suites matching /error-handling/i, when running a test for this ticket, it also runs /lessons/writes-with-error-handling.spec.js, which shows “duplicate key error” and “Not enough data-bearing nodes” before running intended test file.

image

This is not a super big issue, but may be confusing for some people…

Thank you so much for catching this. :slight_smile: Really appreciate it.

Kanika

I arrived here after spending a frustrating time googling for Mongodb error codes. The example in the lecture shows testing for a duplicate key by checking for the string “E11000 duplicate key error collection”. I, for one, am uncomfortable with hard coding strings in my code, since they have a tendency to change over time. I am more comfortable checking for a specific code such as “E11000”. With these thoughts, and considering the example, I assumed that Mongo would maintain a strict list of error codes and their text. I also assumed that it would be readily available if we were expected to write code that looked for specific text. After googling for some time, I never did find such a definitive list. That was frustrating.

Finally, I decided I would simply run the bad code to see what error I got, and then code for that. Amazingly, I did not see a nice error code like ‘E11001 invalid object id’, but rather the string ‘Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters’. I suppose that is the string I am to look for in my code. For this lab, I will do it, but I would never feel that that would be the right way to code in production. Seems way too brittle.

By the way, is there a list of error codes (such as E11000) for MongoDb and where is it?

1 Like