Skip to content

Commit

Permalink
Merge pull request #18 from jessedoyle/exception-hierarchy
Browse files Browse the repository at this point in the history
Version 0.8.0
  • Loading branch information
jessedoyle committed Feb 5, 2016
2 parents fdb72e1 + 1883abf commit e54eb5b
Show file tree
Hide file tree
Showing 18 changed files with 214 additions and 92 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Master (v0.7.1.pre)
# v0.8.0 - Feb 4, 2016

- (_breaking change_) JS errors are now mapped to their proper Crystal exceptions. i.e. JS `SyntaxError` becomes `Duktape::SyntaxError`.
- (_breaking change_) Make all exception classes more consistent. Instances of `Duktape::Error` are all recoverable exceptions that are thrown by the engine at runtime (eg. `Duktape::TypeError`). Instances of `Duktape::InternalError` are generally non-recoverable for a given context (eg. `Duktape::HeapError`).
- Added `call_success`, `call_failure` and `return_undefined` convenience methods that provide the appropriate integer status codes when returning from a native function call.
- Added the `push_global_proc` method that simplifies pushing a named native function to the stack.
- `Duktape::Runtime` instances may now accept a execution timeout value in milliseconds upon creation. [[#15](https://github.com/jessedoyle/duktape.cr/pull/15), [@raydf](https://github.com/raydf)].
Expand Down
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ version: 1.0.0 # your project's version
dependencies:
duktape:
github: jessedoyle/duktape.cr
version: ~> 0.7.0
version: ~> 0.8.0
```
then execute:
Expand Down Expand Up @@ -89,7 +89,7 @@ sbx.eval! <<-JS
JS
```

will raise `Duktape::Error "SyntaxError"`.
will raise `Duktape::SyntaxError`.

## Sandbox vs Context

Expand All @@ -108,7 +108,7 @@ JS

`Duktape::Sandbox` instances may optionally take an execution timeout limit in milliseconds. This provides protection against infinite loops when executing untrusted code.

A `Duktape::Error "RangeError"` exception is raised when the following code executes for longer than specified:
A `Duktape::RangeError` exception is raised when the following code executes for longer than specified:

```crystal
sbx = Duktape::Sandbox.new 500 # 500ms execution time limit
Expand Down Expand Up @@ -178,6 +178,27 @@ The `proc` object that is pushed to the Duktape stack accepts a pointer to a `Co

**Note**: Because it is currently not possible to pass closures to C bindings in Crystal, one must be careful that any variables used in the `proc` must not be referenced or initialized outside the scope of the `proc`. This is why variable names such as `env` are used.

## Exceptions

The following exceptions may be thrown at runtime and may be rescued normally:

* `Duktape::Error`
* `Duktape::EvalError`
* `Duktape::RangeError`
* `Duktape::ReferenceError`
* `Duktape::SyntaxError`
* `Duktape::TypeError`
* `Duktape::URIError`

These exceptions all inherit from `Duktape::Error`, so it may be used as a catch-all for runtime errors.

The following exceptions represent errors internal to the Duktape engine and are generally not recoverable when thrown from a context:

* `Duktape::InternalError`
* `Duktape::HeapError`

These exceptions all inherit from `Duktape::InternalError`.

## Contributing

I'll accept any pull requests that are well tested for bugs/features with Duktape.cr.
Expand Down
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: duktape
version: 0.7.1.pre
version: 0.8.0

authors:
- Jesse Doyle <jdoyle@ualberta.ca>
Expand Down
8 changes: 4 additions & 4 deletions spec/duktape/api/call_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe Duktape::API::Call do
it "should raise if nargs < 0" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /negative argument/ do
expect_raises ArgumentError, /negative argument/ do
ctx.call(-1)
end
end
Expand Down Expand Up @@ -52,7 +52,7 @@ describe Duktape::API::Call do
it "should raise Duktape::Error if error does not exist" do
ctx = Duktape::Context.new

expect_raises(Duktape::Error, /invalid error type/) do
expect_raises(Duktape::TypeError, /invalid error type/) do
ctx.call_failure :invalid
end
end
Expand All @@ -77,7 +77,7 @@ describe Duktape::API::Call do
it "should raise if nargs < 0" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /negative argument/ do
expect_raises ArgumentError, /negative argument/ do
ctx.call_method -1
end
end
Expand Down Expand Up @@ -140,7 +140,7 @@ describe Duktape::API::Call do
it "should raise on negative nargs" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /negative argument/ do
expect_raises ArgumentError, /negative argument/ do
ctx.new -1
end
end
Expand Down
14 changes: 7 additions & 7 deletions spec/duktape/api/compile_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe Duktape::API::Compile do
ctx << invalid_js
ctx << "invalid.js"

expect_raises Duktape::Error, /SyntaxError/ do
expect_raises Duktape::SyntaxError, /parse error/ do
ctx.compile!
end
end
Expand All @@ -103,7 +103,7 @@ describe Duktape::API::Compile do
it "should raise when provided invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /SyntaxError/ do
expect_raises Duktape::SyntaxError, /parse error/ do
ctx.compile! invalid_js
end
end
Expand Down Expand Up @@ -159,7 +159,7 @@ describe Duktape::API::Compile do
it "should raise on invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /SyntaxError/ do
expect_raises Duktape::SyntaxError, /eof or line terminator/ do
ctx.compile_file! "#{JS_SOURCE_PATH}/invalid.js"
end
end
Expand Down Expand Up @@ -195,7 +195,7 @@ describe Duktape::API::Compile do
it "should raise on invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /SyntaxError/ do
expect_raises Duktape::SyntaxError, /parse error/ do
ctx.compile_lstring! invalid_js, invalid_js.size
end
end
Expand Down Expand Up @@ -252,7 +252,7 @@ describe Duktape::API::Compile do
ctx = Duktape::Context.new
ctx << "test.js"

expect_raises Duktape::Error, /SyntaxError/ do
expect_raises Duktape::SyntaxError, /parse error/ do
ctx.compile_lstring_filename! invalid_js, invalid_js.size
end
end
Expand Down Expand Up @@ -291,7 +291,7 @@ describe Duktape::API::Compile do
it "should raise on invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /SyntaxError/ do
expect_raises Duktape::SyntaxError, /parse error/ do
ctx.compile_string! invalid_js
end
end
Expand Down Expand Up @@ -341,7 +341,7 @@ describe Duktape::API::Compile do
ctx = Duktape::Context.new
ctx << "invalid.js"

expect_raises Duktape::Error, /SyntaxError/ do
expect_raises Duktape::SyntaxError, /parse error/ do
ctx.compile_string_filename! invalid_js
end
end
Expand Down
85 changes: 85 additions & 0 deletions spec/duktape/api/error_handling_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,91 @@ describe Duktape::API::ErrorHandling do
end
end

describe "raise_error" do
it "should not raise and return 0 when not given an argument" do
ctx = Duktape::Context.new
val = ctx.raise_error

val.should eq(0)
end

it "should rescue with a Duktape::Error" do
ctx = Duktape::Context.new
ctx.push_error_object LibDUK::ERR_TYPE_ERROR, "test"

begin
ctx.raise_error(-1)
# We should not get this far due to a raise
1.should_not eq(1)
rescue ex : Duktape::Error
1.should eq(1)
end
end

it "should raise a Duktape::Error" do
ctx = Duktape::Context.new
ctx.push_error_object LibDUK::ERR_ERROR, "test"

expect_raises Duktape::Error, /test/ do
ctx.raise_error(-1)
end
end

it "should raise a Duktape::EvalError" do
ctx = Duktape::Context.new
ctx.push_error_object LibDUK::ERR_EVAL_ERROR, "test"

expect_raises Duktape::EvalError, /test/ do
ctx.raise_error(-1)
end
end

it "should raise a Duktape::RangeError" do
ctx = Duktape::Context.new
ctx.push_error_object LibDUK::ERR_RANGE_ERROR, "test"

expect_raises Duktape::RangeError, /test/ do
ctx.raise_error(-1)
end
end

it "should raise a Duktape::ReferenceError" do
ctx = Duktape::Context.new
ctx.push_error_object LibDUK::ERR_REFERENCE_ERROR, "test"

expect_raises Duktape::ReferenceError, /test/ do
ctx.raise_error(-1)
end
end

it "should raise a Duktape::SyntaxError" do
ctx = Duktape::Context.new
ctx.push_error_object LibDUK::ERR_SYNTAX_ERROR, "test"

expect_raises Duktape::SyntaxError, /test/ do
ctx.raise_error(-1)
end
end

it "should raise a Duktape::TypeError" do
ctx = Duktape::Context.new
ctx.push_error_object LibDUK::ERR_TYPE_ERROR, "test"

expect_raises Duktape::TypeError, /test/ do
ctx.raise_error(-1)
end
end

it "should raise a Duktape::URIError" do
ctx = Duktape::Context.new
ctx.push_error_object LibDUK::ERR_URI_ERROR, "test"

expect_raises Duktape::URIError, /test/ do
ctx.raise_error(-1)
end
end
end

# Note: Can't really test this from a proc as
# `push_proc` doesn't get along with Crystal's
# spec library.
Expand Down
22 changes: 11 additions & 11 deletions spec/duktape/api/eval_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe Duktape::API::Eval do
it "should raise if arg contains invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /ReferenceError/ do
expect_raises Duktape::ReferenceError, /identifier '__invalid_identifier' undefined/ do
ctx.eval! invalid_js
end
end
Expand All @@ -72,7 +72,7 @@ describe Duktape::API::Eval do
ctx = Duktape::Context.new
ctx << invalid_js

expect_raises Duktape::Error, /ReferenceError/ do
expect_raises Duktape::ReferenceError, /identifier '__invalid_identifier' undefined/ do
ctx.eval!
end
end
Expand Down Expand Up @@ -114,7 +114,7 @@ describe Duktape::API::Eval do
it "should raise an error on invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /SyntaxError/ do
expect_raises Duktape::SyntaxError, /eof or line terminator/ do
ctx.eval_file! "#{JS_SOURCE_PATH}/invalid.js"
end
end
Expand Down Expand Up @@ -153,7 +153,7 @@ describe Duktape::API::Eval do
# Because the NORESULT flag tells Duktape to
# not push the Error object on the stack after
# failure, we have to look for a StackError
expect_raises Duktape::StackError, /error object missing/ do
expect_raises Duktape::StackError, /stack empty/ do
ctx.eval_file_noresult! "#{JS_SOURCE_PATH}/invalid.js"
end
end
Expand Down Expand Up @@ -186,15 +186,15 @@ describe Duktape::API::Eval do
it "should raise an error on invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /ReferenceError/ do
expect_raises Duktape::ReferenceError, /identifier '__invalid_identifier' undefined/ do
ctx.eval_lstring! invalid_js, invalid_js.size
end
end

it "should raise when length is negative" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /negative string length/ do
expect_raises ArgumentError, /negative string length/ do
ctx.eval_lstring! valid_js, -1
end
end
Expand Down Expand Up @@ -236,15 +236,15 @@ describe Duktape::API::Eval do
it "should raise on invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::StackError, /error object missing/ do
expect_raises Duktape::StackError, /stack empty/ do
ctx.eval_lstring_noresult! invalid_js, invalid_js.size
end
end

it "should raise when length is negative" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /negative string length/ do
expect_raises ArgumentError, /negative string length/ do
ctx.eval_lstring_noresult! valid_js, -1
end
end
Expand Down Expand Up @@ -282,7 +282,7 @@ describe Duktape::API::Eval do
ctx = Duktape::Context.new
ctx << invalid_js

expect_raises Duktape::StackError, /error object missing/ do
expect_raises Duktape::StackError, /stack empty/ do
ctx.eval_noresult!
end
end
Expand Down Expand Up @@ -319,7 +319,7 @@ describe Duktape::API::Eval do
it "should raise on invalid js strings" do
ctx = Duktape::Context.new

expect_raises Duktape::Error, /ReferenceError/ do
expect_raises Duktape::ReferenceError, /identifier '__invalid_identifier' undefined/ do
ctx.eval_string! invalid_js
end
end
Expand Down Expand Up @@ -361,7 +361,7 @@ describe Duktape::API::Eval do
it "should raise StackError on invalid js" do
ctx = Duktape::Context.new

expect_raises Duktape::StackError, /error object missing/ do
expect_raises Duktape::StackError, /stack empty/ do
ctx.eval_string_noresult! invalid_js
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/duktape/api/object_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ describe Duktape::API::Object do
ctx.get_prop(-2)
ctx.set_global_object

expect_raises Duktape::Error, /ReferenceError/ do
expect_raises Duktape::ReferenceError, /identifier 'Duktape' undefined/ do
ctx.eval_string! <<-JS
Duktape.version;
JS
Expand Down
Loading

0 comments on commit e54eb5b

Please sign in to comment.