Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw custom exception class #315

Closed
andheiberg opened this issue Feb 12, 2017 · 8 comments
Closed

Throw custom exception class #315

andheiberg opened this issue Feb 12, 2017 · 8 comments

Comments

@andheiberg
Copy link

andheiberg commented Feb 12, 2017

I would like to be able to throw an custom exceptions to make it clear what is being caught.

I tried creating and throwing an extension of Php::Exception:

class CustomException : public Php::Exception {};

but this gives me no matching conversion for functional-style cast from 'const char *' to 'ParserException' at compile time.

I found one issue (#275) discussing this in 2014, but not a solution.

Is it possible to throw custom exception?

@EmielBruijntjes
Copy link
Member

This is currently not possible

@andheiberg
Copy link
Author

Is there any work to make this doable?

Is there anything I can do?

@sjinks
Copy link
Contributor

sjinks commented Feb 13, 2017

@AndreasHeiberg do you want to throw an exception in C++ and catch it in PHP? Or what exactly are you trying to achieve?

@andheiberg
Copy link
Author

andheiberg commented Feb 13, 2017

@sjinks Yes I would like to throw an exception in my extension and catch it in PHP. That would require me to register a PHP class that extends \Exception in my PHP extension and then throw it from said extension.

In PHP I want something like:

try {
    function_from_my_extension();
}
catch (\MyExtension\Exceptions\CustomOne $e) {
    // something appropriate 
}
catch (\MyExtension\Exceptions\CustomTwo $e) {
    // something appropriate 
}

@sjinks
Copy link
Contributor

sjinks commented Feb 13, 2017

Well, if you don't mind having some low level code…

#include <Zend/zend.h>
#include <Zend/zend_exceptions.h>

// global
zend_class_entry* my_exception_ce;

// ...

extension.onStartup([]() {
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "MyExtension\\Exceptions\\CustomOne", NULL);
    my_exception_ce = zend_register_internal_class_ex(&ce, zend_exception_get_default(), NULL);
});

// Your function
void my_function()
{
    zend_throw_exception_ex(my_exception_ce, 0, "Something bad has happened in %s on line %d", __FILE__, __LINE__);
}

@sjinks
Copy link
Contributor

sjinks commented Feb 13, 2017

if you need to interrupt your C++ code, you will probably need to

throw Php::Exception("...");

right after zend_throw_exception_ex.

@mdumitrean
Copy link

mdumitrean commented Jul 27, 2017

Hmm.... I think this is what you wanted:
Here's the custom PHP Exception I want to throw:

    class CdtException extends Exception {
    	public function __construct($context, $line, $message, $destination = 'cdt-error_log', $code = 0, Exception $previous = null) {
    		parent::__construct(sprintf("[%s/%d] %s", gettype($context) == 'object' ? get_class($context) : $context, $line, $message), $code, $previous);
    		error_log
    		(
    				// Message
    				sprintf("[%s] %s\n", gettype($context) == 'object' ? get_class($context) : $context, $message),
    				// Append to destination
    				3,
    				$destination
    		);
		}
		
		static function createCdtException($file, $line, $message) {
			throw new CdtException($file, $line, $message);
		}
    }

Here is my CPP code (a light wrapper around the real Php CdtException):

class CdtException : public std::exception {
private:
	std::string _file;
	uint64_t _line;
	std::string _message;
public:
	CdtException(std::string file, uint64_t line, std::string message) : std::exception() {
		_file = file;
		_line = line;
		_message = message;

		this->php();
	}
	void php() {
		Php::Value ex("CdtException::createCdtException");
		ex(_file,int2str(_line),_message);
	}
};

Then here's me throwing an exception in CPP:

	throw new CdtException(__FILE__, (uint64_t)__LINE__, "Error creating object");

Here is the output from command line:

PHP Fatal error:  Uncaught exception 'CdtException' with message '[ComponentManager.cpp/121] Error creating object' in /Library/WebServer/Documents/cdtweb/model/helper_objects/Exceptions.php:64

My stack is obviously catching the exception:

{
    "status": "error",
    "data": "",
    "message": "[ComponentManager.cpp/116] Error creating object"
}

Did I miss something? This seems to work.

@sandrokeil
Copy link

@EmielBruijntjes Any plans to support own exception and PHP SPL exception classes? I found that there was a PR with commit 48d706f that adds the support. It should be implemented in origexception.h right? The examples above doesn't worked for me. I'm new to c++.

/cc @Photonios

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants