Skip to content

Commit bd51ea4

Browse files
committed
Importer: Allows importer to return error.
* Adds corresponding tests. Issue URL: sass#651. PR URL: sass#817.
1 parent 33b0b60 commit bd51ea4

File tree

4 files changed

+82
-13
lines changed

4 files changed

+82
-13
lines changed

src/custom_importer_bridge.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,36 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val
1616
for (size_t i = 0; i < array->Length(); ++i) {
1717
Local<Value> value = array->Get(static_cast<uint32_t>(i));
1818

19-
if (!value->IsObject())
19+
if (!value->IsObject()) {
2020
continue;
21+
}
2122

2223
Local<Object> object = Local<Object>::Cast(value);
23-
char* path = create_string(object->Get(NanNew<String>("file")));
24-
char* contents = create_string(object->Get(NanNew<String>("contents")));
2524

26-
imports[i] = sass_make_import_entry(path, (!contents || contents[0] == '\0') ? 0 : strdup(contents), 0);
25+
if (value->IsNativeError()) {
26+
char* message = create_string(object->Get(NanNew<String>("message")));
27+
28+
imports[i] = sass_make_import_entry(0, 0, 0);
29+
30+
sass_import_set_error(imports[i], message, -1, -1);
31+
}
32+
else {
33+
char* path = create_string(object->Get(NanNew<String>("file")));
34+
char* contents = create_string(object->Get(NanNew<String>("contents")));
35+
36+
imports[i] = sass_make_import_entry(path, (!contents || contents[0] == '\0') ? 0 : strdup(contents), 0);
37+
}
2738
}
2839
}
40+
else if (returned_value->IsNativeError()) {
41+
imports = sass_make_import_list(1);
42+
Local<Object> object = Local<Object>::Cast(returned_value);
43+
char* message = create_string(object->Get(NanNew<String>("message")));
44+
45+
imports[0] = sass_make_import_entry(0, 0, 0);
46+
47+
sass_import_set_error(imports[0], message, -1, -1);
48+
}
2949
else if (returned_value->IsObject()) {
3050
imports = sass_make_import_list(1);
3151
Local<Object> object = Local<Object>::Cast(returned_value);
@@ -46,7 +66,7 @@ std::vector<Handle<Value>> CustomImporterBridge::pre_process_args(std::vector<vo
4666
std::vector<Handle<Value>> out;
4767

4868
for (void* ptr : in) {
49-
out.push_back(NanNew<String>((char const*) ptr));
69+
out.push_back(NanNew<String>((char const*)ptr));
5070
}
5171

5272
return out;

test/api.js

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,30 @@ describe('api', function() {
387387
done();
388388
});
389389
});
390+
391+
it('should reflect user-defined error when returned as callback', function(done) {
392+
sass.render({
393+
data: src,
394+
importer: function(url, prev, done) {
395+
done(new Error('doesn\'t exist!'));
396+
}
397+
}, function(error) {
398+
assert.equal(error.message, 'doesn\'t exist!');
399+
done();
400+
});
401+
});
402+
403+
it('should reflect user-defined error with return', function(done) {
404+
sass.render({
405+
data: src,
406+
importer: function() {
407+
return new Error('doesn\'t exist!');
408+
}
409+
}, function(error) {
410+
assert.equal(error.message, 'doesn\'t exist!');
411+
done();
412+
});
413+
});
390414
});
391415

392416
describe('.render(functions)', function() {
@@ -1136,6 +1160,20 @@ describe('api', function() {
11361160
assert.equal(sync, true);
11371161
done();
11381162
});
1163+
1164+
1165+
it('should throw user-defined error', function(done) {
1166+
assert.throws(function() {
1167+
sass.renderSync({
1168+
data: src,
1169+
importer: function() {
1170+
return new Error('doesn\'t exist!');
1171+
}
1172+
});
1173+
}, /doesn\'t exist!/);
1174+
1175+
done();
1176+
});
11391177
});
11401178

11411179
describe('.render({stats: {}})', function() {
@@ -1390,14 +1428,10 @@ describe('api', function() {
13901428
assert.throws(function() {
13911429
fs.renameSync(originalBin, renamedBin);
13921430
process.sass.getBinaryPath(true);
1393-
}, function(err) {
1394-
fs.renameSync(renamedBin, originalBin);
1431+
}, /`libsass` bindings not found. Try reinstalling `node-sass`?/);
13951432

1396-
if ((err instanceof Error) && /`libsass` bindings not found. Try reinstalling `node-sass`?/.test(err)) {
1397-
done();
1398-
return true;
1399-
}
1400-
});
1433+
fs.renameSync(renamedBin, originalBin);
1434+
done();
14011435
});
14021436
});
14031437
});

test/cli.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ describe('cli', function() {
410410
});
411411
});
412412

413-
it('should return error on for invalid importer file path', function(done) {
413+
it('should return error for invalid importer file path', function(done) {
414414
var bin = spawn(cli, [
415415
src, '--output', path.dirname(dest),
416416
'--importer', fixture('non/existing/path')
@@ -421,6 +421,18 @@ describe('cli', function() {
421421
done();
422422
});
423423
});
424+
425+
it('should reflect user-defined Error', function(done) {
426+
var bin = spawn(cli, [
427+
src, '--output', path.dirname(dest),
428+
'--importer', fixture('extras/my_custom_importer_error.js')
429+
]);
430+
431+
bin.stderr.once('data', function(code) {
432+
assert.equal(JSON.parse(code).message, 'doesn\'t exist!');
433+
done();
434+
});
435+
});
424436
});
425437

426438
describe('functions', function() {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function() {
2+
return new Error('doesn\'t exist!');
3+
};

0 commit comments

Comments
 (0)