Is it a good or bad idea throwing Exceptions when validating data?

后端 未结 14 912
你的背包
你的背包 2020-12-07 16:27

When validating data, I\'ve gotten into a habit of doing the following:

Note: I don\'t really have individual booleans for each check. This is just

相关标签:
14条回答
  • 2020-12-07 16:46

    I support MusiGenesis's answer.

    Additionally...


    The performance of throwing an exception is a thousand instructions. It's nothing compared to end-user time, but in inner code it is slow.

    An additional problem is that, using Exceptions, your validation is limited to reporting the first failure (and you will have to do it all again next time to find the next failure).

    0 讨论(0)
  • 2020-12-07 16:47

    So maybe in some languages exception throwing and catching is "costly" but in other languages, throwing and catching exceptions is exactly what's called for.

    In Smalltalk, for example, one could quickly build a multi-tiered exception catching solution. The validation pass could collect up any number of exceptions representing EVERYTHING that's wrong with a particular input data set. Then it would throw them ALL up to a higher-level catcher, responsible for formatting up a human-readable explanation of, again, EVERYTHING that was wrong with the input. In turn it would throw a single exception further up the chain, along with that formatted explanation.

    So... I guess what I'm saying is, exceptions are only bad to throw if you've got no exception handling architecture supporting catching them and doing reasonable things with them, and all your catcher is going to do is EXIT or do something else equally inappropriate.

    0 讨论(0)
  • 2020-12-07 16:47

    This is bad behavior. Exceptions are for Exceptional conditions. They take resources to generate the stack etc. Exceptions should not be used to dictate process flow.

    0 讨论(0)
  • 2020-12-07 16:48

    I would suggest that using exceptions as described in the question (for flow control within a function) is wrong not usually the best idea. I'd go further and saying validation throwing exceptions isn't the best approach; instead return a Boolean and store a list of validation error messages that can be accessed. An accompanying save method could/should throw an exception if it is called on an invalid object.

    Thus if validate fails validation error messages can be displayed to the user (logged, returned. whatever). If validation passes then you can call save. If you call save on an invalid object then get get an appropriate exception.

    Another potential problem with your example code (depending on requirements of course) is it only throws the first validation error that occurs. Imagine this from a users POV:

    • Click save
    • Get an error message
    • Correct error
    • Click save again
    • Get a different error message. Annoying.

    As a user I'd prefer to get all validation errors returned at once so I can correct them all before trying again.

    0 讨论(0)
  • 2020-12-07 16:50

    Personally I like throwing Exceptions for business rule validation (not so much for user input validation) because it forces the problem to be handled upstream. If my business objects returned some kind of validation result, it could be ignored by the caller. Call me a cowboy if you wish :)

    Everyone here is repeating the phrase "exceptions are for exceptional circumstances", but that really doesn't give any understanding of why its bad to use them for unexceptional circumstances. I need more than that. Is the performance hit of throwing exceptions really that bad? Are there any benchmarks available?

    0 讨论(0)
  • 2020-12-07 16:50

    Well, i know it's an old question. But i'll let my opinion here for the googler's who falled here like me:

    1. If you are using a language with a bad try/catch support AVOID THROWING exceptions for data validation;
    2. DO NOT THROW a exception that will not be handled by the caller or alserwhere;
    3. DO NOT THROW a exception if you need to validate the rest of the received data;
    4. You can THROW a exception in cases where the code block cannot continue without the invalid data; And if you do not interrupt the process you can get a unhandled exception;

    An example:

    /*
     * Here it's a common problem i have: Someone pass a list of products i need to
     * retrieve from the database and update some information;
     */
    
    //This is a class to represent the product
    function Product(id, name, price) {
    	this.id = id;
    	this.name = name;
    	this.price = price;
    }
    
    //This is an example function to retrieve the product from the database
    function findProductInDatabase(productId) {
    
    	//If the product exists on the database, the function will return it
    	if (productId == 12) {
    		var product = new Product(12, "Book", 20.5);
    		return product;
    	}
    	
    	//If the product do not exists, it will return null
    	return null;
    }
    
    //This is a function that will receive the productID and will update the received parameters
    function updateProduct(productId, newProductName, newProductPrice) {
    
    	var productFromDatabase = null;
    	var errorMessage = "";
    	
    	//Retrieve the product
    	productFromDatabase = findProductInDatabase(productId);
    
    	//If the product do not exist, i need to interrupt de method imediatily and alert the caller
    	if (!productFromDatabase) {
    		throw "Product not found";
    	}
    	
    	//Validate the other parameters, but in this case	i can validate all the parameters
    	if (newProductPrice < 10) {
    		errorMessage += "the price is too low";
    	}
    	
    	if (newProductName.includes("<")) {
    		
    		//If already has a error message in the variable i append " and " to the message make sense
    		if (errorMessage) {
    			errorMessage += " and ";
    		}
    		
    		errorMessage += "the new name has invalid characters";
    	}
    	
    	if (errorMessage) {
    		//if theres any error, i will throw a exception with the messages
    		throw errorMessage;
    	}
    }
    
    //This parte is where the method id called;
    try {
    	updateProduct(9, "Book", 10.5);
    } catch (exception) {
    	console.log("Case 1: " + exception);
    }
    try {
    	updateProduct(12, "<Book", 9);
    } catch (exception) {
    	console.log("Case 2: " + exception);
    }

    0 讨论(0)
提交回复
热议问题