2015-02-27 24 views
6

W kompilacji projektu Node.js z LoopbackJS muszę przechowywać dane podczas żądania.Node.js proces.domain jest niezdefiniowany czasami

Więc użyłem domain cechę:

// pre-processing middleware 
app.use(function (req, res, next) { 
    // create per request domain instance 
    var domain = require('domain').create(); 

    // save request and response to domain, to make it accessible everywhere 
    domain.req = req; 
    domain.res = res; 
    domain.run(next); 
}); 

Później w wymaganym modułem:

Model.beforeRemote('**', function(oContext, oModel, next) { 
    // Save method name for later use 
    process.domain.remoteContext = {   /* Here is an error thrown */ 
     methodName: oContext.method.name 
    }; 
    ... 
    process.domain.res.send() // example of usage 
}) 

ale kiedy zrobić wniosek Safari lub IE, process.domain czasami niezdefiniowana! Żądanie z przeglądarki Chrome lub Firefox działa zgodnie z oczekiwaniami. Jakieś sugestie?

odpowiedź Błąd:

{"error":{"name":"TypeError","status":500,"message":"Cannot set property 'remoteContext' of undefined","stack":"TypeError: Cannot set property 'remoteContext' of undefined\n at module.exports (/Users/igormatyushkin/projects/Yash/server/hooks/admin-remote.js:12:34)\n at Function.Model.setup.ModelCtor.beforeRemote.args (/Users/igormatyushkin/projects/Yash/node_modules/loopback/lib/model.js:184:9)\n at execStack (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:363:13)\n at RemoteObjects.execHooks (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:372:10)\n at RemoteObjects.invokeMethodInContext (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:512:8)\n at async.series.results (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:610:21)\n at _asyncMap (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:249:17)\n at async.eachSeries.iterate (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:149:13)\n at async.eachSeries (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:165:9)\n at _asyncMap (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:248:13)"}} 
+0

Czy możesz pokazać nam kod, w którym domena jest niezdefiniowana? Czy uzyskujesz dostęp do domeny z tego samego zakresu, w którym ją zdefiniowałeś? W twoim przykładzie kodu faktycznie nie przypisujesz domeny do procesu - zakładam, że robisz to gdzie indziej w twoim kodzie?Proszę również opublikować ślad stosu prowadzący do niezdefiniowanego błędu, może on zawierać wskazówkę lub dwie. –

+0

@RobertRossmann, zaktualizowałem kod i dodano zgłoszony błąd. "Process.domain" jest inicjowane przez węzeł, gdy wywoływane jest 'domain.run()' i mam dostęp do 'process.domain.remoteContext' później w innych wymaganych modułach. – IvanZh

Odpowiedz

2

Dowiedziałem się, że w momencie tworzenia kreacja wiążąca explisity wiąże się z domeną, rozwiązuje niezdefiniowane domeny w stosie wykonawczym.

app.use(function (req, res, next) { 
    // create per request domain instance 
    domain.create().run(function() { 
    // explicit binding 
    process.domain.add(req) 
    process.domain.add(res) 
    // save request to domain, to make it accessible everywhere 
    process.domain.req = req; 
    process.domain.res = res; 
    next() 
    }); 
}); 

Nie wiem, dlaczego tak się dzieje, dlatego pozostawiam pytanie otwarte na inne możliwe porady.

1

Warto wspomnieć, że domeny are not meant to be used to handle errors in this manner. Domeny mają natomiast służyć do bezpiecznego awaryjnego zawieszania modułów całej aplikacji (na przykład, być może chcesz uruchomić kod innej firmy w piaskownicy). Domena nie jest tutaj potrzebna (oczywiście, jeśli możesz ją używać).

Ponadto, process.domain jest ustawiany tylko wtedy, gdy dana funkcja działa z poziomu stosu domeny. Nie podajesz informacji o stronie wywołania Modelu, więc mogę tylko założyć, że Twój model jest wywoływany spoza tego stosu, co powoduje błąd.

Biorąc pod uwagę, że jesteś podpinania do beforeRemote, który wykonuje przed wykonywany jest zdalne działanie, mam zamiar założyć, że jest wywoływana z zewnątrz stosu domeny, a więc process.domain jest niezdefiniowany oczekuje zachowania.

+0

Załóżmy, że w process.domain brakuje stosu wywołań, ale dzieje się tak tylko wtedy, gdy zgłoszę żądanie z przeglądarki Safari lub IE. Żądanie z przeglądarki Chrome lub Firefox działa zgodnie z oczekiwaniami. – IvanZh

+0

W twoim pytaniu nie wspomniano, że próbowałeś z Chrome lub Firefoksem, dlatego założyłem założenie - tylko że wypróbowałeś je w Safari i IE. –

1

Dla czytelników tego pytania ważne jest, aby wiedzieć, że Node's Domain module został wycofany i nie powinien być używany.

Jeśli przyszedłeś tutaj, szukając rozwiązania tego problemu, lepiej będzie poszukać czegoś innego niż moduł Domeny.

Ten moduł czeka na wycofanie. Po sfinalizowaniu zastępczego interfejsu API ten moduł będzie w pełni przestarzały. Większość użytkowników końcowych nie powinna mieć powodów do korzystania z tego modułu. Użytkownicy, którzy bezwzględnie muszą mieć zapewnioną funkcjonalność domen, mogą na tym polegać, ale powinni spodziewać się migracji do innego rozwiązania w przyszłości.

Chociaż nie jest to technicznie odpowiedź na pytanie OP, uważam, że jest to właściwe "rozwiązanie" dla większości czytelników tego pytania.

Alternatywą dla używania domeny jest moduł continuation-local-storage.

Powiązane problemy